选择器意图 - 从图库或相机中选择

Chooser Intent - Pick from gallery or camera

所以我设法创建了一个选择器意图来从图库中挑选图像或拍照。我面临的问题是,当我选择“相机”并在返回 activity 时拍照时,我收到错误消息说我的应用程序意外停止工作,而当我使用我的图库或 google+照片或文件资源管理器然后它工作得很好。我无法找出错误。以下是我启动意图和处理 activity 结果的代码:

启动意图的函数,在单击 ImageView 时调用:

private void openImageIntent() {

    // Determine Uri of camera image to save.
    final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
    root.mkdirs();
    final String fname = "img_" + System.currentTimeMillis() + ".jpg";
    final File sdImageMainDirectory = new File(root, fname);
    outputFileUri = Uri.fromFile(sdImageMainDirectory);

    // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for(ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        cameraIntents.add(intent);
    }

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));

    startActivityForResult(chooserIntent, 0);
}

onActivityResult方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent returnIntent) {
    super.onActivityResult(resultCode, requestCode, returnIntent);
    if(requestCode == 0) {
        if(resultCode == RESULT_OK) {
            final boolean isCamera;
            if(returnIntent == null)
            {
                isCamera = true;
            }
            else
            {
                final String action = returnIntent.getAction();
                if(action == null)
                {
                    isCamera = false;
                }
                else
                {
                    isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }

            Uri selectedImageUri;
            if(isCamera)
            {
                selectedImageUri = outputFileUri; 
                ivProfilePicture.setImageURI(selectedImageUri); //Troublesome

            }
            else
            {
                selectedImageUri = returnIntent == null ? null : returnIntent.getData();
                ivProfilePicture.setImageURI(selectedImageUri); //Perfectly fine.
            }
        }
    }
}

我不知道为什么会这样,任何帮助将不胜感激。谢谢。

当然还有 logcat:

01-29 16:19:40.886: E/AndroidRuntime(14234): FATAL EXCEPTION: main 01-29 16:19:40.886: E/AndroidRuntime(14234): java.lang.RuntimeException: Unable to resume activity {com.footstapps.letsmeet/com.footstapps.letsmeet.ProfileInfoActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=null} to activity {com.footstapps.letsmeet/com.footstapps.letsmeet.ProfileInfoActivity}: java.lang.NullPointerException 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2797) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2826) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.access0(ActivityThread.java:144) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1259) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.os.Handler.dispatchMessage(Handler.java:99) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.os.Looper.loop(Looper.java:137) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.main(ActivityThread.java:5140) 01-29 16:19:40.886: E/AndroidRuntime(14234): at java.lang.reflect.Method.invokeNative(Native Method) 01-29 16:19:40.886: E/AndroidRuntime(14234): at java.lang.reflect.Method.invoke(Method.java:525) 01-29 16:19:40.886: E/AndroidRuntime(14234): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 01-29 16:19:40.886: E/AndroidRuntime(14234): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 01-29 16:19:40.886: E/AndroidRuntime(14234): at dalvik.system.NativeStart.main(Native Method) 01-29 16:19:40.886: E/AndroidRuntime(14234): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=null} to activity {com.footstapps.letsmeet/com.footstapps.letsmeet.ProfileInfoActivity}: java.lang.NullPointerException 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.deliverResults(ActivityThread.java:3374) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2784) 01-29 16:19:40.886: E/AndroidRuntime(14234): ... 12 more 01-29 16:19:40.886: E/AndroidRuntime(14234): Caused by: java.lang.NullPointerException 01-29 16:19:40.886: E/AndroidRuntime(14234): at com.footstapps.letsmeet.ProfileInfoActivity.onActivityResult(ProfileInfoActivity.java:160) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.Activity.dispatchActivityResult(Activity.java:5322) 01-29 16:19:40.886: E/AndroidRuntime(14234): at android.app.ActivityThread.deliverResults(ActivityThread.java:3370) 01-29 16:19:40.886: E/AndroidRuntime(14234): ... 13 more

编辑: 我调试了应用程序并用 Uri.EMPTY 初始化了 selectedImageUri。这消除了错误,但现在 ImageView 没有得到更新,但是当我 select 来自图库的图像时它被更新了。

显然 Android 正在清除内存或打开一个新的 activity 而不是恢复上一个。保存 activity 的当前状态可以解决这个问题。对于此示例,您需要保存具有图像 uri 的变量。

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("outputFileUri",outputFileUri);
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    outputFileUri = savedInstanceState.getString("outputFileUri");
}

由于 onRestoreInstanceState 将在 onActivityResult 之前调用,因此 outputFileUri 的值不会为空。