Я использую библиотеку для обрезки фотографий (версия 2.7 здесь: https://github.com/ArthurHub/Android-Image-Cropper)), чтобы выбрать и обрезать изображение с помощью приложений галереи (таких как галерея Samsung, фотографии Google, файлы и т. Д.).
Библиотека работает, запуская намерение выбора с Intent.ACTION_GET_CONTENT, и после того, как пользователь выбирает изображение, Uri передается в представление обрезки, которое открывает растровое изображение.
В некоторых ситуациях мне нужно сбросить обрезку, автоматически используя Uri из фотографии, выбранной пользователем в последний раз. Итак, после того, как пользователь выбирает изображение, я запоминаю Uri, затем использую тот же Uri, чтобы начать этап обрезки (который декодирует растровое изображение).
Это работает для галереи Samsung, но у меня есть проблема с Google Photos, которая выдает исключение SecurityException при повторном открытии URI. Таким образом, выбор изображения с фотографиями Google работает правильно в первый раз, когда пользователь выбирает только изображение. Когда я пытаюсь передать тот же Uri (когда я сбрасываю обрезку), я получаю исключение ниже (это также происходит с «Files» - я тестировал на эмуляторе и Motorola один):
java.lang.RuntimeException: Failed to load sampled bitmap: content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253Ace62f6ca-6054-486b-bbb1-b6145ac50272/ORIGINAL/NONE/27402515
Permission Denial: opening provider com.google.android.apps.photos.contentprovider.impl.MediaContentProvider from ProcessRecord{82bb7a9 12497:app.myapp/u0a188} (pid=12497, uid=10188) that is not exported from UID 10093
at com.theartofdev.edmodo.cropper.BitmapUtils.decodeSampledBitmap(BitmapUtils.java:130)
at com.theartofdev.edmodo.cropper.BitmapLoadingWorkerTask.doInBackground(BitmapLoadingWorkerTask.java:73)
at com.theartofdev.edmodo.cropper.BitmapLoadingWorkerTask.doInBackground(BitmapLoadingWorkerTask.java:24)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.impl.MediaContentProvider from ProcessRecord{82bb7a9 12497:app.myapp/u0a188} (pid=12497, uid=10188) that is not exported from UID 10093
at android.os.Parcel.createException(Parcel.java:1950)
at android.os.Parcel.readException(Parcel.java:1918)
at android.os.Parcel.readException(Parcel.java:1868)
at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:4118)
Код, используемый для отображения пользователю, из какого приложения выбрать фотографию:
List<Intent> allIntents = new ArrayList<>();
PackageManager packageManager = this.getPackageManager();
boolean includeCamera = useCamera;
// collect all camera intents if Camera permission is available
if (!CropImage.isExplicitCameraPermissionRequired(this) && includeCamera) {
allIntents.addAll(CropImage.getCameraIntents(this, packageManager));
}
boolean includeDocuments = false;
if (useGallery) {
List<Intent> galleryIntents =
CropImage.getGalleryIntents(packageManager, Intent.ACTION_GET_CONTENT, includeDocuments);
if (galleryIntents.size() == 0) {
// if no intents found for get-content try pick intent action (Huawei P9).
galleryIntents = CropImage.getGalleryIntents(packageManager, Intent.ACTION_PICK, includeDocuments);
}
allIntents.addAll(galleryIntents);
}
Intent target;
if (allIntents.isEmpty()) {
target = new Intent();
} else {
target = allIntents.get(allIntents.size() - 1);
allIntents.remove(allIntents.size() - 1);
}
// Create a chooser from the main intent
Intent chooserIntent = Intent.createChooser(target, "Choose");
// Add all other intents
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));
this.startActivityForResult(
chooserIntent
, CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE);
И метод CropImage.getGalleryIntents:
public static List<Intent> getGalleryIntents(
@NonNull PackageManager packageManager, String action, boolean includeDocuments) {
List<Intent> intents = new ArrayList<>();
Intent galleryIntent =
action == Intent.ACTION_GET_CONTENT
? new Intent(action)
: new Intent(action, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
galleryIntent.setType("image/*");
List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
for (ResolveInfo res : listGallery) {
Intent intent = new Intent(galleryIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
intents.add(intent);
}
// remove documents intent
if (!includeDocuments) {
for (Intent intent : intents) {
if (intent
.getComponent()
.getClassName()
.equals("com.android.documentsui.DocumentsActivity")) {
intents.remove(intent);
break;
}
}
}
return intents;
}
У меня есть правильное решение или обходной путь для этого? Спасибо.