Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camera Result always returns RESULT_CANCELED

I want to take pictures with my camera. I just need them temporally so i do the following:

private void takePicture() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    if (intent.resolveActivity(this.getActivity().getPackageManager()) != null) {
        try {
            this.imageFile = File.createTempFile("CROP_SHOT", ".jpg", this.getActivity().getCacheDir());

            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(this.imageFile));
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);

            this.startActivityForResult(intent, Globals.REQUEST_TAKE_PHOTO);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Unfortunately the result code RESULT_CANCELED in my onActivityResult

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.v("PictureEdit", "onActivityResult");

    super.onActivityResult(requestCode, resultCode, data);

    if(resultCode == Activity.RESULT_OK) {
        if(requestCode == Globals.REQUEST_TAKE_PHOTO) {
            Log.v("PictureEdit", "onActivityResult take photo");

            this.startCropImage(Uri.fromFile(this.imageFile));
        } else if (requestCode == Globals.REQUEST_PICK_PHOTO) {
            Log.v("PictureEdit", "onActivityResult pick photo");

            this.startCropImage(data.getData());
        } else if (requestCode == Globals.REQUEST_CROP_PHOTO) {
            Log.v("PictureEdit", "onActivityResult crop photo");

            this.imageEncoded = data.getStringExtra(Globals.KEY_IMAGE_ENCODED);

            this.imageView.setImageBitmap(Images.decodeImage(imageEncoded));
            this.buttonSave.setEnabled(true);
        } else {
            Log.v("PictureEdit", "onActivityResult requestCode: " + requestCode + ", result: " + resultCode);
        }
    } else {
        Log.v("PictureEdit", "onActivityResult resultCode is not ok: " + resultCode);
    }
}

Every solutions i found so far on stackoverflow and in the web did not solve my problem. I use the cache directory for creating a temp file:

File.createTempFile("CROP_SHOT", ".jpg", this.getActivity().getCacheDir());

And i have the correct permissions:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

Picking images from my smartphone always works fine:

private void pickPicture() {
    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

    this.startActivityForResult(intent, Globals.REQUEST_PICK_PHOTO);
}

So why is the camera always returning RESULT_CANCELED?

It is appearing on Nexus 4 with Android 6.0 and on Samsung Galaxy S III with Android 4.2.

like image 518
Mulgard Avatar asked Feb 08 '16 14:02

Mulgard


2 Answers

What @CommonsWare mentioned is right, but if you still want to follow what the official documentation said, what I did was granting those 3rd party applications, which are able to handle your intent, a temporary read and write URI permissions:

List<ResolveInfo> resolvedIntentActivities = getContext().getPackageManager().queryIntentActivities(takePhotoIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities) {
    String packageName = resolvedIntentInfo.activityInfo.packageName;
    getContext().grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

The above code snippet should be inserted before your startActivityForResult().

like image 165
Sira Lam Avatar answered Nov 10 '22 18:11

Sira Lam


I use the cache directory for creating a temp file:

First, a third-party camera app has no rights to work with your app's private cache directory on internal storage.

Second, you are not supposed to create the file. The camera app is supposed to create the file. Some camera apps may get confused and refuse to overwrite your file.

So, create a File object pointing to a location on external storage (e.g., getExternalCacheDir()), but do not create the file yet. Use that File object as the basis for your EXTRA_OUTPUT value.

Also note that MediaStore.EXTRA_VIDEO_QUALITY is for recording videos; it has no meaning for ACTION_IMAGE_CAPTURE.

like image 29
CommonsWare Avatar answered Nov 10 '22 18:11

CommonsWare