在将 uri 转换为位图、获取字节、压缩 - 在异步任务中然后上传到服务器时遇到问题



您好,我正在开发通过使用设备拍照或从设备上传现有图像将图像上传到Firebase的应用程序。后者有效。但是,为了拍照,我的代码停止在我将 uri 转换为位图但不确定原因的地方。 错误" 由以下原因引起: java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'java.lang.String android.net.Uri.getScheme(('

我知道它的基本,但我几天来一直在努力,请帮忙。

日志猫

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
at android.content.ContentResolver.openInputStream(ContentResolver.java:646)
at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:1101)
at rungene.com.forsale.PostFragment$ImageResizeBackground.doInBackground(PostFragment.java:202)
at rungene.com.forsale.PostFragment$ImageResizeBackground.doInBackground(PostFragment.java:173)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:818) 
10-23 20:56:26.094 788-788/? E/WifiTrafficPoller: TRAFFIC_STATS_POLL true Token 1122 num clients 11

后期片段:

import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.OnProgressListener;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import rungene.com.forsale.models.Post;
import rungene.com.forsale.util.UniversalImageLoader;
public class PostFragment extends android.support.v4.app.Fragment  implements PhotoDialogFragment.PhotoListener{
private static final String TAG = "PostFragment";
private EditText postTitle,postDescription,postPrice,postCountry,postStateProvince,postCity,postEmail;
private ImageView postImage;
private Button buttonPost;
private ProgressBar progressBarPost;
private Bitmap selectedBitmap;
private Uri selectedUri;
private byte[] uploadBytes;
private double mProgress=0;

@Override
public void getImageBitMap(Bitmap bitmap) {
Log.d(TAG, "getImageBitMap: assign image to imageview");
postImage.setImageBitmap(bitmap);
//assign to global variables
selectedBitmap = bitmap;
selectedUri = null;

}
@Override
public void getImagePath(Uri imagePath) {
Log.d(TAG, "getImagePath: setting image to imageview");
UniversalImageLoader.setImage(imagePath.toString(),postImage);
//assign to global variables
selectedBitmap = null;
selectedUri = imagePath;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.post_fragment,container,false);
postTitle = view.findViewById(R.id.postTitle);
postDescription = view.findViewById(R.id.postDescription);
postPrice = view.findViewById(R.id.postPrice);
postCountry = view.findViewById(R.id.postCountry);
postStateProvince = view.findViewById(R.id.postStateProvince);
postCity = view.findViewById(R.id.postCity);
postEmail = view.findViewById(R.id.postEmail);
postImage = view.findViewById(R.id.postImage);
buttonPost = view.findViewById(R.id.buttonPost);
progressBarPost = view.findViewById(R.id.progressBarPost);

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
photoDialog();
return view;
}
private void photoDialog(){
postImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: opening upload photo dialog");
Toast.makeText(getActivity(), "Image View Tapped", Toast.LENGTH_SHORT).show();
PhotoDialogFragment photoDialogFragment = new PhotoDialogFragment();
photoDialogFragment.show(getFragmentManager(),getString(R.string.photo_select));
photoDialogFragment.setTargetFragment(PostFragment.this,1);
}
});
buttonPost.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: attemptng to post");
if (!isEmpty(postTitle.getText().toString())
&& !isEmpty(postDescription.getText().toString())
&& !isEmpty(postPrice.getText().toString())
&& !isEmpty(postCountry.getText().toString())
&& !isEmpty(postStateProvince.getText().toString())
&& !isEmpty(postCity.getText().toString())
&& !isEmpty(postEmail.getText().toString())){
//if we have a bitmap and no uri
if (selectedBitmap != null && selectedUri==null){
uploadPhotoFirebase(selectedBitmap);
}
//we have no bitmap but uri
else if (selectedBitmap==null && selectedUri!= null){
uploadPhotoFirebase(selectedUri);
}

}else {
Toast.makeText(getActivity(), "Please fill all the fields", Toast.LENGTH_SHORT).show();
}
}
});
}
private void uploadPhotoFirebase(Bitmap bitmap) {
Log.d(TAG, "uploadPhotoFirebase: uploading a new bitmap to storage");

ImageResizeBackground imageResizeBackground = new ImageResizeBackground(bitmap);
Uri uri = null;
imageResizeBackground.execute(uri);
}
private void uploadPhotoFirebase(Uri uriImagePath) {
Log.d(TAG, "uploadPhotoFirebase: uploading new uri to storage");
ImageResizeBackground imageResizeBackground = new ImageResizeBackground(null);
imageResizeBackground.execute(uriImagePath);
}

public class ImageResizeBackground extends AsyncTask<Uri,Integer,byte[]>{
Bitmap mBitmap;
public ImageResizeBackground(Bitmap bitmap) {
if (mBitmap!=null){
this.mBitmap = bitmap;
}

}
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(getActivity(), "Compressing image", Toast.LENGTH_SHORT).show();
showProgressBar();
}
@Override
protected byte[] doInBackground(Uri... params) {
Log.d(TAG, "doInBackground: started.");
if(mBitmap == null){
try{

mBitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), params[0]);
}catch (IOException e){
Log.e(TAG, "doInBackground: IOException: " + e.getMessage());
}
}
byte[] bytes = null;
Log.d(TAG, "doInBackground: megabytes before compression: " + mBitmap.getByteCount() / 1000000 );
bytes = getBytesFromBitmap(mBitmap, 100);
Log.d(TAG, "doInBackground: megabytes before compression: " + bytes.length / 1000000 );
return bytes;
}


@Override
protected void onPostExecute(byte[] bytes) {
super.onPostExecute(bytes);
uploadBytes = bytes;
hideProgressBar();
//execute the upload task
implementingUploadTask();
}
}
private void implementingUploadTask(){
Toast.makeText(getActivity(), "uploading the image", Toast.LENGTH_SHORT).show();
final String postId = FirebaseDatabase.getInstance().getReference().push().getKey();
final StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("posts/users"
+ FirebaseAuth.getInstance().getCurrentUser().getUid() +"/"+postId +"post_image" );

UploadTask uploadTask = storageReference.putBytes(uploadBytes);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getActivity(), "Post success", Toast.LENGTH_SHORT).show();
//inserting the download url into the firebase database
Uri uriFirebase = taskSnapshot.getDownloadUrl();
Log.d(TAG, "onSuccess: firebase download uri"+uriFirebase.toString());
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
Post post = new Post();
post.setCity(postCity.getText().toString());
post.setContact_email(postEmail.getText().toString());
post.setCity(postCity.getText().toString());
post.setPost_id(postId);
post.setDescription(postDescription.getText().toString());
post.setImage(uriFirebase.toString());
post.setState_province(postStateProvince.getText().toString());
post.setCountry(postCountry.getText().toString());
post.setPrice(postPrice.getText().toString());
post.setUser_id(FirebaseAuth.getInstance().getCurrentUser().getUid());
databaseReference.child(getString(R.string.node_users))
.child(postId)
.setValue(post);
resetFields();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getActivity(), "Could not upload!", Toast.LENGTH_SHORT).show();

}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double currentProgress = (100*taskSnapshot.getBytesTransferred()/taskSnapshot.getTotalByteCount());
if (currentProgress>(mProgress+15)){
mProgress = (100*taskSnapshot.getBytesTransferred()/taskSnapshot.getTotalByteCount());
Log.d(TAG, "onProgress: upload is "+mProgress +"% done");
Toast.makeText(getActivity(), mProgress+" % ", Toast.LENGTH_SHORT).show();
}
}
});

}
public static byte[] getBytesFromBitmap(Bitmap bitmap, int quality){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality,stream);
return stream.toByteArray();

}

private void resetFields(){
UniversalImageLoader.setImage("",postImage);
postTitle.setText("");
postDescription.setText("");
postPrice.setText("");
postCountry.setText("");
postStateProvince.setText("");
postCity.setText("");
postEmail.setText("");
postEmail.setText("");
}
private void showProgressBar(){
progressBarPost.setVisibility(View.VISIBLE);
}
private void hideProgressBar(){
if (progressBarPost.getVisibility() == View.VISIBLE){
progressBarPost.setVisibility(View.INVISIBLE);
}
}

/**
* Return true if the @param is null
* @param string
* @return
*/
private boolean isEmpty(String string){
return string.equals("");
}
}

PhotoDialogFragment:

package rungene.com.forsale;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class PhotoDialogFragment extends android.support.v4.app.DialogFragment {
private static final String TAG = "PhotoDialogFragment";
private static final  int pickRequestCode = 12;
private static final int cameraRequestCode = 13;

public interface PhotoListener{
void getImagePath(Uri imagePath);
void getImageBitMap(Bitmap bitmap);
}
PhotoListener photoListener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.selectphoto_dialog,container,false);
TextView textPhoneMemory = view.findViewById(R.id.textPhoneMemory);
textPhoneMemory.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: Accessing phone memory");

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent,pickRequestCode);
}
});
TextView textTakePhoto = view.findViewById(R.id.textTakePhoto);
textTakePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: Starting camera");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,cameraRequestCode);
}
});
return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//results when selecting a photo form gallery
if (requestCode==pickRequestCode && resultCode== Activity.RESULT_OK){
Uri uri = data.getData();
Log.d(TAG, "onActivityResult: image uri"+uri);
//send Uri to post fragment and dismiss dialog.
photoListener.getImagePath(uri);
getDialog().dismiss();
}
//results when taking a photo with camera.
else if (requestCode==cameraRequestCode && resultCode==Activity.RESULT_OK ){
Log.d(TAG, "onActivityResult: Done taking photo");
Bitmap bitmap;
bitmap = (Bitmap) data.getExtras().get("data");
//send the bitmap to Postfragment and dismiss dialog.
photoListener.getImageBitMap(bitmap);
getDialog().dismiss();
}
}
@Override
public void onAttach(Context context) {
try {
photoListener =(PhotoListener)getTargetFragment();
}catch (ClassCastException e){
Log.d(TAG, "onAttach:ClassCastException "+e.getMessage());
}
super.onAttach(context);
}
}

First

public class ImageResizeBackground extends AsyncTask<Uri,Integer,byte[]>

您似乎没有在任何地方使用 Uri,所以为什么不将其更改为 Void 并停止传递 Null,因为它不需要参数来执行((

第二

在 onActivityResult 中访问返回的数据之前,您应该检查返回的数据是否为空,因为它可以为空。

最后,不要假设数据是 URI。放置一个断点,看看它返回了什么。你可能会得到一些不同的东西。在不知道您正在运行的操作系统和您要运行的流程的情况下,我只能假设数据是一个 Uri。因为如果一切都做得完全正确,它很可能会。但是看看它是否在附加功能中,而不是直接在数据中。

相关内容

最新更新