Camera Result always returns RESULT_CANCELED

半城伤御伤魂 提交于 2019-12-23 07:10:17

问题


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.


回答1:


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.




回答2:


A better solution is to use the FileProvider. So your app don't need any permission to write to external storage and your app can grant the camera the permission to write to the

Start the camera with permission to use app folders:

Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
camera.putExtra(MediaStore.EXTRA_OUTPUT, getPhotoFile(context));
camera.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
camera.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);

public static Uri getPhotoFile(Context context) {
    File file = new File(context.getExternalCacheDir(), "camera.jpg");
    return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider.files", file);
}



回答3:


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().



来源:https://stackoverflow.com/questions/35272403/camera-result-always-returns-result-canceled

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!