如何通过对话 - 活动通信检索图像或'imagePath'?

时间:2018-05-01 21:03:04

标签: android image interface dialog android-dialogfragment

我有ImageView打开dialog,其中包含2个选项

  1. External Memory

  2. 中选择照片
  3. 或使用Camera

  4. 获取新的

    打开dialog,对话框成功permissions,然后打开相机或内存

    但是当我从记忆中选择照片或通过相机批准拍照时,它会给我一个error

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

    以下是我如何从Dialog

    调用Activity
    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存在问题吗? 我该如何解决?

1 个答案:

答案 0 :(得分:0)

错误发生在On Your ActivityResult方法中。您正在访问null对象的接口上的方法。

请设置调试器<​​/ p>

@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在您的错误中显示为null,因此您应该在调用getImagePath()的位置设置断点,并查看该对象为null。接下来,您只需要查看它在何处/如何设置为null。