Исключение java.lang.SecurityException: чтение..MediaDocumentsProvider ... требуется android.permission.MANAGE_DOCUMENTS или 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;
}

ОШИБКА в Android 5.1.1 Исключение java.lang.SecurityException: Отказ в доступе : чтение содержимого uri com.android.providers.media.MediaDocumentsProvider://com.android.providers.media.documents/document/image%3A6617 из pid=19207, uid=10260 требует android.permission.MANAGE_DOCUMENTS или grantUriPermission()

ОШИБКА в Android 8.0.0 Exception java.lang.SecurityException: Отказ в разрешении: открывающий поставщик com.android.providers.media.MediaDocumentsProvider из ProcessRecord{5c1039e 5061:com.mobotechnology.cvmaker/u0a219} (pid=5061, uid=10219) требует, чтобы вы получили доступ с помощью ACTION_OPEN_DOCUMENT или связанных API

2 ответа

Я пытаюсь сохранить Uri и использовать этот Uri позже

Это будет работать для Uri с file схема. Это не будет работать для большинства Uri значения с content схема. Они больше похожи на HTTP-URL для аутентифицированного веб-сайта - этот URL хорош, пока ваш сеанс жив, но впоследствии бесполезен.

Если вы получите Uri с помощью ACTION_OPEN_DOCUMENT, ACTION_CREATE_DOCUMENT, или же ACTION_OPEN_DOCUMENT_TREEи ты звонишь takePersistableUriPermission() на ContentResolver поставляя Uriтогда вы можете смело настаивать на том, что Uri, Вы будете иметь доступ к контенту на неопределенный срок до тех пор, пока пользователь не отменит доступ или контент не изменится (например, будет удален), так что его Uri больше не действителен

Любой другой contentUri (например, ACTION_GET_CONTENT) хорошо только в течение очень короткого времени. Единственный вариант здесь - скопировать содержимое в какой-то файл, которым вы управляете (например, в 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
        }
    }
}
Другие вопросы по тегам