android - 将图像发送到 PHP 服务器时,android.content.ContentResolver.openInputStream 出现 NullPointer 异常
问题描述
我使用 Volley 教程从教程 Android Upload Image to Server修改
在本教程中,当用户选择图像时,脚本直接上传到服务器。所以我修改了当用户选择图像时,图像首先显示在 imageview 上,然后,当用户单击“sendtoserver”按钮时,该图像将与另一个 EditText 一起发送到服务器。
首先,我完成了选择图像按钮,我选择的图像显示在 imageview 上。
第二,当我单击“sendtoserver”按钮时,我收到关于 getContentResolver() 的错误,这里是我的 MainActivity 代码
package com.example.celmira.uploadgambar;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.Volley;
import com.squareup.picasso.Picasso;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
//ImageView to display image selected
ImageView imageView;
//edittext for getting the tags input
EditText editTextTags;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//initializing views
imageView = (ImageView) findViewById(R.id.imageView);
editTextTags = (EditText) findViewById(R.id.editTextTags);
//mengecek permission, jika blm diijinkan, maka buka setting atau keluar apps
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
finish();
startActivity(intent);
return;
}
//get image from gallery when clicked
findViewById(R.id.buttonUploadImage).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//if the tags edittext is empty
//we will throw input error
if (editTextTags.getText().toString().trim().isEmpty()) {
editTextTags.setError("Enter tags first");
editTextTags.requestFocus();
return;
}
//if everything is ok we will open image chooser
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 100);
}
});
// SENDING IMAGE AND TAG TO SERVER WHEN BUTTON sendtoserver clicked
findViewById(R.id.sendtoserver).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri imageUri = getIntent().getData();
try {
//getting bitmap object from uri
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
Log.d("eek",bitmap.toString());
//function to send to server
uploadBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == RESULT_OK && data != null) {
//getting the image Uri
Uri imageUri = data.getData();
try {
//getting bitmap object from uri
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
//displaying selected image to imageview
Picasso.get().load(imageUri).into(imageView);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* The method is taking Bitmap as an argument
* then it will return the byte[] array for the given bitmap
* and we will send this array to the server
* here we are using PNG Compression with 80% quality
* you can give quality between 0 to 100
* 0 means worse quality
* 100 means best quality
* */
public byte[] getFileDataFromDrawable(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 80, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
private void uploadBitmap(final Bitmap bitmap) {
//getting the tag from the edittext
final String tags = editTextTags.getText().toString().trim();
//our custom volley request
VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, "http://192.168.166.2/MyApi/Api.php?apicall=uploadpic",
new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
try {
JSONObject obj = new JSONObject(new String(response.data));
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
/*
* If you want to add more parameters with the image
* you can do it here
* here we have only one parameter with the image
* which is tags
* */
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("tags", tags);
return params;
}
/*
* Here we are passing image by renaming it with a unique name
* */
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
long imagename = System.currentTimeMillis();
params.put("pic", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap)));
return params;
}
};
//adding the request to volley
Volley.newRequestQueue(this).add(volleyMultipartRequest);
}
}
这里是导致错误的脚本
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
这就是错误信息
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.content.ContentResolver.openInputStream(ContentResolver.java:481)
at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:792)
at com.example.celmira.uploadgambar.MainActivity$2.onClick(MainActivity.java:94)
如何获取我可以传递给 MediaStore.Images.Media.getBitmap() 的 getContentResolver()
解决方案
选择 iamge 后上传:
移至uploadBitmap(bitmap);
_onActivityResult()
点击按钮后上传:
首先创建全局图片url
private Uri imageUri;
在你的代码上面onActivityResult
像你一样填写
imageUri = data.getData();
并在呼叫按钮时发送
findViewById(R.id.sendtoserver).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//THIS LINE REMOVED
//Uri imageUri = getIntent().getData();
try {
//getting bitmap object from uri
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
Log.d("eek",bitmap.toString());
//function to send to server
uploadBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
});
推荐阅读
- android - 在开发模式下测试媒体应用程序的问题
- excel - 相关到期日期
- css - 如何在引导程序 4 中使组件垂直居中且等高列
- css - 在线激活 wordpress 主题时,Divs 不会浮动 - 在 localhost 上很好
- php - 当我加载它时,网页没有返回我的应用程序的名称。它留空。(拉拉维尔)
- javascript - 了解嵌套 if 语句如何影响循环递增
- python - 用 Pandas 将宽 df 融为长
- python - 将多页pdf连接成单页pdf
- java - 如何使用 MVC 设计模式观察嵌套对象
- java - Hibernate ManyToMany realation