Android Q RecoverableSecurityException未授予访问权限

时间:2020-03-03 22:22:40

标签: android exception android-contentresolver

我正在尝试对Android API 29的文件处理进行排序。由于我在与Android上的文件相关的任何内容方面都不是明星,因此遇到了问题。

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

我需要在哪里寻找解决此问题的方法? ContentResolver只有一个结果,它显示在另一个错误中的文件路径(与上面的错误一起显示)是正确的:E/MediaProvider: Couldn't delete /storage/emulated/0/Pictures/**app**/**filename**.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"/>

1 个答案:

答案 0 :(得分:1)

使用Content resolver delete调用删除图像时,我在Android Q中遇到了非常相似的问题。事实证明,尽管我捕获了RecoverableSecurityException以获取从android画廊中删除图片的权限-但它仍然引发错误,由于该应用没有权限,因此无法删除该文件(因此,在打开Goog​​le 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周,找不到其他地方描述的问题或解决方案。但是如果需要,我们很乐意扩展或更新答案。