10
votes

I have the following code which request user to pick an image from photo apps or capture an image by camera apps:

    // 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);

And my code of 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

}

These codes work well in the previous android versions. However, when I updated my nexus 5 to Android 5.1.1 (together updating the camera app to latest version), the codes doesn't work well when requesting default camera to capture photos.

According to debugger, when the code reaches final String action = data.getAction(); after capturing an image by the default camera app, the result Intent data is always an empty Intent (not null though) that contains no action , extras, data, etc. So final String action = data.getAction(); always return null and fails my following codes.

I guess something is changed for the default camera app in 5.1.1 so the camera intent behavior is different. But then I get no idea on how to make it works.

Any suggestions would be appreciate. Thanks!

4
Have you solved your problem i got same problem tooAntwan
@Tony sorry I didn't, my workaround at the end is just saving the photo in external storage, Make a static global variable of the URI after it is stored, and check if this static variable is not Null when onActivityResult is called...(And when everytime it call the camera, set this Global variable to null first)passer

4 Answers

3
votes

I have added one more condition. It seems working fine without any problem in 5.1.1 as well as in different API levels

if(data == null){
 isCamera = true;
}else if(data.getData() == null){
 isCamera = true;
}
else{
  //....
1
votes

Your guess is correct, there is a change in Lollipop: http://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE

public static final String ACTION_IMAGE_CAPTURE Added in API level 3

Standard Intent action that can be sent to have the camera application capture an image and return it.

The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri value of EXTRA_OUTPUT. As of LOLLIPOP, this uri can also be supplied through setClipData(ClipData). If using this approach, you still must supply the uri through the EXTRA_OUTPUT field for compatibility with old applications. If you don't set a ClipData, it will be copied there for you when calling startActivity(Intent).

You need to set the ClipData in the intent, that's how i do it

intent.setClipData(ClipData.newRawUri(null, Uri.fromFile(file)));

in your case i think it is

intent.setClipData(ClipData.newRawUri(null,  outputFileUri));

Also i don't set MediaStore.EXTRA_OUTPUT, because for me it returns null data, i dont't know how you don't get a null data, setting MediaStore.EXTRA_OUTPUT, but that's another thing: Camera activity returning null android

1
votes

I got same issue and i added

mFileTemp.getParentFile().mkdirs();

before passing uri to intent and its resolved for me.

0
votes

I found the solution of this after some research and testing.

The solution is to make either file or path of file object in static while creating temp file.

private static String path;

 private File createImageFile() throws IOException {
        File storageDir = Environment.getExternalStorageDirectory();
        File image = File.createTempFile(
                "hoivia_image",  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );
path=image.getpath();
        return image;
    }

This might be happening because the current activity objects become null at onActivityResult().

Hope it helps you.