4

I'm in the process of updating an Android app to scoped storage and the problem I'm facing now is that on my app users can select a set of images to be processed automatically (and they can choose to overwrite the original image).

The problem is, when I'm trying to overwrite the original image from its Uri, Android throws a RecoverableSecurityException, which displays a dialog to the user asking consent to modify that photo.

What I want to know is if it's possible to instead show a permission dialog but for the whole set of, for example, 10 images at once, instead of having to show a dialog for each one.

I tried using the applyBatch method of ContentResolver (the code below simulates the issue), but the consent dialog only shows for the first updated image.

val values = ContentValues().apply {
                put(MediaStore.Images.Media.DATE_MODIFIED, System.currentTimeMillis())
            }
            val ops = arrayListOf<ContentProviderOperation>()
            for (image in galleryImages) {
                ops.add(ContentProviderOperation.newUpdate(image.uri)
                        .withValues(values)
                        .build())
            }
            context.contentResolver.applyBatch(MediaStore.AUTHORITY, ops)

Any ideas on this? Thank you.

4

2 回答 2

2

不幸的是,在 Android Q 中是不可能的。但是,在 2019 年 Android 峰会上,该团队表示在下一个 Android 版本中可以进行批量编辑和删除,因此应该是在未来的“R”版本中。

观看下一个视频,从 18:50 开始,他们简要地谈论它:

https://youtu.be/UnJ3amzJM94

Android Q 中唯一的解决方案是获取您要操作的目录的 SAF 权限,并使用 DocuentFile API 而不是 MediaStore。

于 2019-10-25T20:52:50.770 回答
0

另外,对于 android 11,我找到了一种无需额外权限请求即可通过捕获 RecoverableSecurityException 并抛出我自己的异常来解决它的方法:

try {
    //try to modify
} catch (RecoverableSecurityException e) {
    List<Uri> uris = //map photo list to uri
    PendingIntent pIntent = MediaStore.createWriteRequest(contentResolver, uris);
    throw new RecoverableSecurityExceptionExt(pIntent);
}


public class RecoverableSecurityExceptionExt extends SecurityException {

    private final PendingIntent pIntent;

    public RecoverableSecurityExceptionExt(PendingIntent pIntent) {
        this.pIntent = pIntent;
    }

    public PendingIntent getPIntent() {
        return pIntent;
    }
}

然后捕获第二个异常,从 PendingIntent 获取 IntentSender 并像常规 RecoverableSecurityException 一样使用 startIntentSenderForResult(...) 等处理它

于 2020-12-11T11:28:12.337 回答