异常 java.lang.SecurityException:读取 ..MediaDocumentsProvider ... 需要 android.permission.MANAGE_DOCUMENTS,或 grantUriPermission()

Exception java.lang.SecurityException: reading ..MediaDocumentsProvider ... requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()

我在尝试为个人资料图片选择图片时仅在某些设备上发现了这个问题。在模拟器中检查时没有看到这些问题,但在应用程序的实时版本中,此用户面临这些问题。 从 firebase 崩溃报告中截取的屏幕截图。请帮助我找出问题所在。

AndroidMenifest.xml

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

SomeActivity.java

private void pickProfilePictureTask() {

    Intent intent = null;
    if (Build.VERSION.SDK_INT > 19) {

        intent = new Intent(Intent.ACTION_OPEN_DOCUMENT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.addCategory(Intent.CATEGORY_OPENABLE);

    } else {

        intent = new Intent(Intent.ACTION_GET_CONTENT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    }

    intent.setType("image/*");
    startActivityForResult(intent, IMAGE_PICKER_REQUEST);


}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == IMAGE_PICKER_REQUEST && resultCode == Activity.RESULT_OK) {


        if (data != null) {
            /**Getting bitmap
             *
             * InputStream inputStream = getActivity().getContentResolver().openInputStream(data.getData());
             * Bitmap userPicBitmap = BitmapFactory.decodeStream(inputStream);
             */
            File file = new File(getFileNameFromURI(data.getData()));
            String imageName = file.getPath();
            uploadProfilePicture.setText(imageName);
            userProfilePicUri = data.getData() + "";

        }


    }
}

private String getFileNameFromURI(Uri contentURI) {
    String result;
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) {
        result = contentURI.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME);
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}

Android5.1.1中的错误异常java.lang.SecurityException:权限被拒绝:读取com.android.providers.media.MediaDocumentsProvider uri content://com.android.providers.media.documents/document/image%3A6617 from pid=19207, uid=10260 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()

Android 8.0.0 异常 java.lang.SecurityException 中的错误:权限被拒绝:从 ProcessRecord{5c1039e [=46= 打开提供程序 com.android.providers.media.MediaDocumentsProvider ].mobotechnology.cvmaker/u0a219} (pid=5061, uid=10219) 要求您使用 ACTION_OPEN_DOCUMENT 或相关 API

获得访问权限

I am trying to persist the Uri and use that Uri later

这适用于 Urifile 方案。它不适用于大多数 Uri 具有 content 方案的值。这些更类似于经过身份验证的网站的 HTTP URL — URL 在您的会话处于活动状态时很好,但之后就没用了。

如果您通过ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENTACTION_OPEN_DOCUMENT_TREE获得Uri并且 你在 ContentResolver 上调用 takePersistableUriPermission() 提供 Uri 然后 你可以安全地坚持 Uri。您将可以无限期地访问内容,直到用户撤销访问权限或内容发生重大变化(例如,被删除)以致其 Uri 不再有效。

任何其他 content Uri(例如,ACTION_GET_CONTENT)只是好的 for a very short time。您在这里唯一的选择是将内容复制到您控制的某个文件(例如,在 getCacheDir() 中)并保存该文件的路径。

试试这个:

public static final int KITKAT_VALUE = 1002;

Intent intent;

if (Build.VERSION.SDK_INT < 19) {
    intent = new Intent();
    intent.setAction(Intent.ACTION_GET_CONTENT);
    intent.setType("*/*");
    startActivityForResult(intent, KITKAT_VALUE);
} else {
    intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*");
    startActivityForResult(intent, KITKAT_VALUE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == KITKAT_VALUE ) {
        if (resultCode == Activity.RESULT_OK) {
            // do something here
        }
    }
}