Android 5.1.1默认摄像头在捕获图像后返回onActivityResult中的空意图

pas*_*ser 10 camera android android-intent android-camera-intent

我有以下代码请求用户从照片应用程序中选择图像或通过相机应用程序捕获图像:

    // Camera
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = fragment.getActivity().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[]{}));

    fragment.startActivityForResult(chooserIntent, UPLOAD_IMAGE_ACTIVITY_REQUEST_CODE);
Run Code Online (Sandbox Code Playgroud)

我的onActivityResult代码:

if(requestCode == UPLOAD_IMAGE_ACTIVITY_REQUEST_CODE)
{
    final boolean isCamera;
    if(data == null)
    {
        isCamera = true;
    }
    else
    {
        final String action = data.getAction(); // data is always empty here after capture image by default camera in 5.1.1!
        if(action == null)
        {
            isCamera = false;
        }
        else
        {
            isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        }
    }

    //do sth according to value of isCamera

}
Run Code Online (Sandbox Code Playgroud)

这些代码在以前的Android版本中运行良好.但是,当我将我的nexus 5更新为Android 5.1.1(将相机应用程序更新到最新版本)时,在请求默认相机拍摄照片时,代码效果不佳.

根据调试器,当代码final String action = data.getAction();通过默认的相机应用程序捕获图像后到达时,结果Intent data始终是一个空的Intent(虽然不是null),它不包含任何动作,附加内容,数据等.所以final String action = data.getAction();总是返回null并且失败了我的跟随码.

我想在5.1.1中默认的相机应用程序有所改变,因此相机的意图行为是不同的.但后来我不知道如何让它发挥作用.

任何建议都会很感激.谢谢!

ism*_*a3l 1

您的猜测是正确的,Lollipop 发生了变化:http://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE

public static final String ACTION_IMAGE_CAPTURE 添加到 API 级别 3

可以发送标准 Intent 操作以使相机应用程序捕获图像并将其返回。

调用者可以传递额外的 EXTRA_OUTPUT 来控制该图像的写入位置。如果 EXTRA_OUTPUT 不存在,则小尺寸图像将作为额外字段中的 Bitmap 对象返回。这对于只需要小图像的应用程序非常有用。如果 EXTRA_OUTPUT 存在,则全尺寸图像将写入 EXTRA_OUTPUT 的 Uri 值。从 LOLLIPOP 开始,此 uri 也可以通过 setClipData(ClipData) 提供。如果使用此方法,您仍然必须通过 EXTRA_OUTPUT 字段提供 uri,以便与旧应用程序兼容。如果你没有设置ClipData,它会在调用startActivity(Intent)时为你复制到那里。

您需要在意图中设置 ClipData,这就是我的做法

intent.setClipData(ClipData.newRawUri(null, Uri.fromFile(file)));
Run Code Online (Sandbox Code Playgroud)

就你而言,我认为是

intent.setClipData(ClipData.newRawUri(null,  outputFileUri));
Run Code Online (Sandbox Code Playgroud)

另外,我不设置 MediaStore.EXTRA_OUTPUT,因为对我来说它返回空数据,我不知道你如何在设置 MediaStore.EXTRA_OUTPUT 时得不到空数据,但这是另一回事:Camera Activity returns null android