MediaDocumentsProvider的权限拒绝

qua*_*ato 6 permissions android android-intent

我有这些作为我的权限:

<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" />
Run Code Online (Sandbox Code Playgroud)

我在openInputStream行上收到了权限拒绝错误:

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();
            }
        }
Run Code Online (Sandbox Code Playgroud)

我首先加载我的图像

@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);
Run Code Online (Sandbox Code Playgroud)

然后保存图像uri:

            String backgroundURI = imageUri.toString();
            int backgroundID = 0;
            mStore.backgroundImageURI = backgroundURI;
            mStore.backgroundImageNumber= backgroundID;
            mStore.save();
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

? 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)
Run Code Online (Sandbox Code Playgroud)

MediaDocumentsProvider当我恢复活动并尝试加载URI时,为什么我会获得权限崩溃?我认为通过获得许可,我会永久保留许可.

cxw*_*cxw 1

看来您正在使用“从这里获取最新数据”和SELECT_PHOTO这里。正确的?假设情况是这样的话——

SELECT_PHOTO示例使用ACTION_PICK来选择照片。 引用

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);  
Run Code Online (Sandbox Code Playgroud)

然而,正如所指出的Intent.ACTION_PICK不能保证持久性。相反,使用Intent.ACTION_OPEN_DOCUMENT. 来自API 文档,适用于 API 19 或更高版本:

所有选定的文档都将返回到调用应用程序,并授予持久的读写权限。如果要在设备重新启动后保持对文档的访问,则需要使用 takePersistableUriPermission(Uri, int) 显式获取持久权限。

尝试

Intent photoPickerIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);  
Run Code Online (Sandbox Code Playgroud)

看看你做得如何。