Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permission denial from MediaDocumentsProvider

I have these as my permissions:

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

I'm getting a permission denial error here on the openInputStream line:

if(bgUri != null && !bgUri.isEmpty()) {
            try {
                InputStream inputStream = context.getContentResolver().openInputStream(Uri.parse(bgUri));   // <-- error
                return Drawable.createFromStream(inputStream, bgUri);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

I first load my image with

@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    if (requestCode == SELECT_PHOTO && resultCode == Activity.RESULT_OK) {
        try {
            final Uri imageUri = imageReturnedIntent.getData();

            final int takeFlags = imageReturnedIntent.getFlags()
                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            // Check for the freshest data.
            mContext.getContentResolver().takePersistableUriPermission(imageUri, takeFlags);

then save the image uri:

            String backgroundURI = imageUri.toString();
            int backgroundID = 0;
            mStore.backgroundImageURI = backgroundURI;
            mStore.backgroundImageNumber= backgroundID;
            mStore.save();

Stack trace:

﹕ FATAL EXCEPTION: main
Process: com.myapp.pocketandroid, PID: 1284
java.lang.RuntimeException: Unable to resume activity {com.myapp.pocketandroid/com.myapp.pocketandroid.MainActivity}: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{52946004 1284:com.myapp.pocketandroid/u0a60} (pid=1284, uid=10060) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2774)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{52946004 1284:com.myapp.pocketandroid/u0a60} (pid=1284, uid=10060) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
        at android.os.Parcel.readException(Parcel.java:1465)
        at android.os.Parcel.readException(Parcel.java:1419)
        at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2848)
        at android.app.ActivityThread.acquireProvider(ActivityThread.java:4399)
        at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2208)
        at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425)
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1047)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:904)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:629)
        at com.myapp.pocketandroid.Utils.BackgroundImageManager.background(BackgroundImageManager.java:29)
        at com.myapp.pocketandroid.BaseActivity.setBackground(BaseActivity.java:83)
        at com.myapp.pocketandroid.BaseActivity.onResume(BaseActivity.java:44)

Why do I get the MediaDocumentsProvider permission crash when I resume my activity and attempt to load the URI? I thought that by taking the permission I keep the permission permanently.

like image 537
quantumpotato Avatar asked Sep 09 '15 18:09

quantumpotato


1 Answers

It appears you are using the "get freshest data" from here and the SELECT_PHOTO from here. Correct? Assuming that's the case ---

The SELECT_PHOTO example uses an ACTION_PICK to choose the photo. Quoting:

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);  

However, as pointed out, Intent.ACTION_PICK has no guarantees about persistability. Instead, use Intent.ACTION_OPEN_DOCUMENT. From the API docs, applicable to API 19 or higher:

All selected documents are returned to the calling application with persistable read and write permission grants. If you want to maintain access to the documents across device reboots, you need to explicitly take the persistable permissions using takePersistableUriPermission(Uri, int).

Try

Intent photoPickerIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);  

and see how you do.

like image 146
cxw Avatar answered Nov 03 '22 05:11

cxw