Android Q RecoverableSecurityException 不授予访问权限

标签 android exception android-contentresolver

我正在尝试对 Android API 29 的文件处理进行排序。由于我在与 Android 上的文件相关的任何事情上都不是明星,所以我遇到了问题。

当我向应用程序添加图像时,我可以使用 contentResolver.delete(deleteUri, null, null); 删除它们,一切正常。但是,当应用程序被删除然后重新安装时,它会给我一个 RecoverableSecurityException ,这已被考虑在内,我已经做到了,以便向文件请求权限才能删除它。当授予权限并且我尝试再次删除该文件时,它仍然给我 android.app.RecoverableSecurityException:**app**.debug 无法访问 content://media/external/images/media/280。它已从 ContentResolver 中删除,因为它在任何库中都不再可见,并且在查询时不会返回任何结果,但该文件仍然“物理上”位于设备上。

我需要在哪里寻找解决此问题的方法? ContentResolver 只有一个结果,它在另一个错误中显示的文件路径(与上述错误一起显示)是正确的:E/MediaProvider: Couldn't delete/storage/emulated/0/Pictures/* *应用程序**/**文件名**.jpeg

删除文件功能:

Cursor c = getCursorFromContentResolver(fileName);

        if (c != null && c.moveToFirst())
        {
            long id = c.getLong(c.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
            Uri deleteUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
            try
            {
                contentResolver.delete(deleteUri, null, null);
            }catch (RecoverableSecurityException e)
            {
                //After the below Intent returns, the current function is run again
                activity.startIntentSenderForResult(e.getUserAction().getActionIntent().getIntentSender(), requestCode, null, 0, 0, 0, null);
            }
            c.close();
            return true;
        }

请求其他权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

最佳答案

当使用内容解析器删除调用删除图像时,我在 Android Q 中遇到了非常类似的问题。事实证明,尽管我捕获了 RecoverableSecurityException 以获得从 Android 图库中删除图像的权限 - 它仍然抛出一个错误,无法删除该文件,因为该应用程序没有权限(因此在打开 Google Photos 后,它会扫描图像并找到“未删除”的图像使其返回)。这是我看到与您的问题相同的错误的地方。当我在 Android R 文件上尝试相同的代码时,没有回来。

阅读完这个问题后,我尝试使用 SAF 作为解决方案。我设法永久删除图像的方法是让用户使用 Intent.ACTION_OPEN_DOCUMENT_TREE

选择图像目录(在我的例子中是 DCIM/Camera)

然后,当按下删除按钮时,我捕获了父文件夹的 Uri 以及该文件夹中文件的名称:

 String filename = queryUriName(content, photoUri);

 DocumentFile docF = DocumentFile.fromTreeUri(context,myTree);
 Boolean docex = docF.exists();
 String idDoc = DocumentsContract.getTreeDocumentId(myTree);
 idDoc = idDoc + "/"+filename;
 Uri childrenUri = DocumentsContract.buildDocumentUriUsingTree(myTree,idDoc);

 DocumentFile childfile = DocumentFile.fromSingleUri(context,childrenUri);
 Boolean chex = childfile.exists();
 System.out.println("child exist: "+ chex+ " file name is " + filename +"   "+idDoc);

这允许删除实际文件,据我所知,它不会抛出任何错误并且文件消失了。

请谨慎对待,因为我已经进入 Android 开发大约 3 周了,在其他地方找不到描述的问题或解决方案。但如果需要的话,我们很乐意扩展或更新答案。

关于Android Q RecoverableSecurityException 不授予访问权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60516401/

相关文章:

java - 实现自己的 Android CursorAdapter 用于搜索建议 - 未知异常

android - 如何在 RelativeLayout 中设置 fragment 在中心的位置

perl - 在 Perl 中捕捉信号最优雅的方法是什么?

android - Koin: NoBeanDefFoundException, 检查你的模块定义

android - 将 gradle 设置为 Android O (API 26)

c++ - 我应该只对无效输入使用异常处理吗?

scala - 在 Scala 中正确扩展 Java 异常的最佳方法是什么?

android - 安全内容提供者

android - `getContentResolver().openInputStream(uri)` 抛出 FileNotFoundException

android - 无法使用 ContentResolver 查询方法,NoSuchMethodError