Исключение 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
больше не действителен
Любой другой content
Uri
(например, 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
}
}
}