Android

Having trouble implementing ACTION_OPEN_DOCUMENT to my project

Возникли проблемы с реализацией ACTION_OPEN_DOCUMENT в моем проекте

У меня есть AddActivity, который позволяет вам получать URI либо из изображения, которое вы можете сделать с камеры, либо из изображения, которое вы можете выбрать из галереи. Затем вы можете перейти к DetailsActivity, чтобы просмотреть изображение. У меня это работает прямо сейчас, пока вы не перезагрузите устройство. После перезагрузки и попытки перейти к DetailsActivity для этого изображения возникает ошибка:

Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{3a5e86d 2915:jeremy.com.wineofmine/u0a321} (pid=2915, uid=10321) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

Я зашел на страницу разработки Android "Открывать файлы с помощью платформы доступа к хранилищу" и прочитал раздел "Постоянные разрешения". Однако у меня возникли проблемы с применением этого в моем проекте.

Я думаю, главное, чего я не понимаю, это то, что похоже, что вам нужно вызвать intent (в моем случае внутри DetailsActivity ), но у меня там даже нет intent .

Вот намерение, которое позволяет вам выбрать изображение из галереи. Это в AddActivity:

Intent intentGallery = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intentGallery.addCategory(Intent.CATEGORY_OPENABLE);
intentGallery.setType("image/*");
intentGallery.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intentGallery.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(intentGallery, SELECT_IMAGE);

В DetailsActivity именно здесь происходит сбой:

imageURI = Uri.parse(cursor.getString(cursor.getColumnIndexOrThrow(WineContract.WineEntry.COLUMN_WINE_IMAGE)));

bitmap = null;
try {
//If the cursor does not have anything in the image column, set the image to null, with a height so the textviews look decent
if (cursor.isNull(cursor.getColumnIndexOrThrow(WineContract.WineEntry.COLUMN_WINE_IMAGE))){
mFullImage.setImageBitmap(null);
mFullImage.setMaxHeight(300);
}else{
//remake the bitmap from the URI in the image column
//********This next line is where the program crashes**********
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageURI);
mFullImage.setImageBitmap(bitmap);

}

Могу ли я получить некоторую помощь с выяснением, как применить это к моему проекту?

Переведено автоматически
Ответ 1

Для обработки результатов разрешения вместо onRequestPermissionsResult, как показано ниже

 @Override
public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case General.REQUESTPERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//reload my activity with permission granted or use the features that required the permission

} else {
Messenger.makeToast(getContext(), R.string.noPermissionMarshmallow);
}
break;
}
}

и сохранить реализацию разрешения, как показано ниже, в вашем методе onActivityResult

@Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//if ok user selected a file
if (resultCode == RESULT_OK) {
Uri sourceTreeUri = data.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getContext().getContentResolver().takePersistableUriPermission(sourceTreeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
}
}
Ответ 2

В onActivityResult(), вызовите takePersistableUriPermission() на ContentResolver, передавая Uri который у вас есть вместе с флагами режима, которые указывают, какой доступ вы хотите (чтение, запись, оба).

Ответ 3

немного поздно, но... Нам нужно предоставить постоянное разрешение Uri. Вместо того, чтобы делать это на onActivityResult в отличие от предыдущих ответов, я предпочитаю добавить его в качестве флага:

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).also {
it.addCategory(Intent.CATEGORY_OPENABLE)
it.type = "image/*"
it.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
it.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}

Кроме того, стоит отметить, что постоянное разрешение доступно только для Intent.ACTION_OPEN_DOCUMENT и НЕ Intent.ACTION_GET_CONTENT, тогда как последнее является одноразовым.

Ответ 4

Проблему с отказом в разрешении необходимо решить при первом получении URI. Если вы используете registerForActivityResult() вместо startActivityForResult()

    // Kotlin
private val pickImage = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// you will get result here in result.data
val uri = result.data?.data!!
requireActivity().contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
// Do something else with the URI. E.g, save the URI as a string in the database
}
}
java android