如何通过Dialog-Activity通讯获取图片或'imagePath'?

How to retrieve image or 'imagePath' through Dialog-Activity Communication?

我有一个 ImageView 打开一个 dialog 有 2 个选项

  1. 到 select 照片来自 External Memory

  2. 或使用 Camera

  3. 获取新的

它打开 dialog 并且对话成功 permissions 然后打开相机或内存

但当我从内存中 select 照片或批准相机拍摄的照片时,它会给我一个 error

我在 dialog fragment 中使用 OnPhotoReceivedListener interface 来检索 photoimagePath

这是我如何从 Activity

调用 Dialog
public class EditNoteActivity extends AppCompatActivity implements ChoosePhotoDialog.OnPhotoReceivedListener{
private String mSelectedImagePath;

private static final int REQUEST_CODE = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_edit_note);

      mSelectedImagePath = null;

    ImageView addImageIV = (ImageView) findViewById(R.id.ivAddImage);
    addImageIV.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            /*
            Make sure all permissions have been verified before opening the dialog
             */
            for(int i = 0; i < Permissions.PERMISSIONS.length; i++){
                String[] permission = {Permissions.PERMISSIONS[i]};
                if(checkPermission(permission)){
                    if(i == Permissions.PERMISSIONS.length - 1){
                        Log.d(TAG, "onClick: opening the 'image selection dialog box'.");
                        ChoosePhotoDialog dialog = new ChoosePhotoDialog();
                        dialog.show(getSupportFragmentManager(), "ChoosePhotoDialog");
                    }
                }else{
                    verifyPermissions(permission);
                }
            }
        }
    });

/**
 * Retrieves the selected image from the bundle (coming from ChoosePhotoDialog)
 * @param bitmap
 */
@Override
public void getBitmapImage(Bitmap bitmap) {
    Log.d(TAG, "getBitmapImage: got the bitmap: " + bitmap);
    //get the bitmap from 'ChangePhotoDialog'
    if(bitmap != null) {
        compressBitmap(bitmap, 70);
        //TODO: Save Image and get It's Url
    }
}

@Override
public void getImagePath(String imagePath) {
    Log.d(TAG, "getImagePath: got the image path: " + imagePath);

    if( !imagePath.equals("")){
        imagePath = imagePath.replace(":/", "://");
        mSelectedImagePath = imagePath;
        mImgUrls += StringManipulation.imgSerialize(new String[]{imagePath, "Description"});
        initRecyclerView(mImgUrls);
    }
}

public Bitmap compressBitmap(Bitmap bitmap, int quality){
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream);
    return bitmap;
}

这是我的 Dialog class

public class ChoosePhotoDialog extends DialogFragment {

private static final String TAG = "ChoosePhotoDialog";

public interface OnPhotoReceivedListener{
    public void getBitmapImage(Bitmap bitmap);
    public void getImagePath(String imagePath);
}

OnPhotoReceivedListener mOnPhotoReceived;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.dialog_camera_or_memory, container, false);

    //initalize the textview for starting the camera
    TextView takePhoto = (TextView) view.findViewById(R.id.tvTakeCameraPhoto);
    takePhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: starting camera.");
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, Permissions.CAMERA_REQUEST_CODE);
        }
    });

    //Initialize the textview for choosing an image from memory
    TextView selectPhoto = (TextView) view.findViewById(R.id.tvChoosePhotoFromMemory);
    selectPhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: accessing phones memory.");
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("image/*");
            startActivityForResult(intent, Permissions.PICK_FILE_REQUEST_CODE);
        }
    });

    // Cancel button for closing the dialog
    TextView cancelDialog = (TextView) view.findViewById(R.id.tvCancelTakingPhoto);
    cancelDialog.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: closing dialog.");
            getDialog().dismiss();
        }
    });

    return view;
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    try{
        mOnPhotoReceived = (OnPhotoReceivedListener) getTargetFragment();
    }catch (ClassCastException e){
        Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    /*
    Results when taking a new image with camera
     */
    if(requestCode == Permissions.CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK){
        Log.d(TAG, "onActivityResult: done taking a picture.");

        //get the new image bitmap
        Bitmap bitmap = (Bitmap) data.getExtras().get("data");
        Log.d(TAG, "onActivityResult: received bitmap: " + bitmap);

        //send the bitmap and fragment to the interface
        mOnPhotoReceived.getBitmapImage(bitmap);
        getDialog().dismiss();
    }

    /*
    Results when selecting new image from phone memory
     */
    if(requestCode == Permissions.PICK_FILE_REQUEST_CODE && resultCode == Activity.RESULT_OK){
        Uri selectedImageUri = data.getData();
        File file = new File(selectedImageUri.toString());
        Log.d(TAG, "onActivityResult: images: " + file.getPath());


        //send the bitmap and fragment to the interface
        mOnPhotoReceived.getImagePath(file.getPath());
        getDialog().dismiss();

    }
}
}

这就是错误

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65544, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/image:14786 flg=0x1 launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } }} to activity {com.ahmed_smae.everynote/com.ahmed_smae.everynote.EditNoteActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.ahmed_smae.everynote.Utils.ChoosePhotoDialog$OnPhotoReceivedListener.getImagePath(java.lang.String)' on a null object reference

你觉得interface有问题吗? 我该如何解决?

错误出在您的 ActivityResult 方法中。您正在访问空对象接口上的方法。

请设置您的调试器

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    try{
        mOnPhotoReceived = (OnPhotoReceivedListener) getTargetFragment();
    }catch (ClassCastException e){
        Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
    }
}

然后确认 getTargetFragment() 正在运行。 因为我怀疑这是返回 null 或者它在你访问它之前的某个时候被取消了。

mOnPhotoReceived 在您的错误中似乎为空,因此您应该在调用 getImagePath() 的位置设置断点并查看对象是否为空。接下来你只需要看到where/how它被设置为null。