使用 ACTION_OPEN_DOCUMENT_TREE 访问外部存储时 Android Q 上的 SecurityException
SecurityException on Android Q for acessing ExternalStorage with ACTION_OPEN_DOCUMENT_TREE
我正在尝试从特定文件夹中获取所有图像以显示在回收站视图中,但无论如何,我都收到了 SecurityException。
我目前正在按照以下方式进行操作:
selecting 文件夹的代码
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
lastRequest = REQUEST_IMAGENS;
startActivityForResult(i, REQUEST_IMAGENS);
onActivityResult
getContentResolver().takePersistableUriPermission(data.getData(),data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
并获取每个单独的位图(这部分特别是我尝试了许多不同的变体,但结果都相同)
BitmapFactory.decodeStream(xContext.getContentResolver().openInputStream(Uri.parse(stringUri + "%3A" + (archiveName + ".png"))));
我认为问题出在最后一段代码上,但我真的不知道还能尝试什么。
我得到的异常是:
java.lang.SecurityException: Permission Denial: reading com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/tree/primary%3ADownload%2FSaurus%20-%20Cadastro%20-%20Imagens%3A2171.png from pid=13239, uid=10425 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
我已经使用 getPersistedUriPermissions 检索了持久化权限,它包含以下 uri:
content://com.android.externalstorage.documents/tree/primary%3ADownload%2FSaurus%20-%20Cadastro%20-%20Imagens
我几乎可以肯定我不能像我一样手动附加文件名,但我不知道我必须做什么。
我读过其他帖子,有很多不同的答案,但 none 有效,我尝试了几乎所有我能找到的东西。
感谢任何帮助,谢谢。
已编辑:
问题是我只希望用户 select 文件夹,而不是所有图像,然后我将在文件夹中搜索我想要的图像,在我省略的循环中,因为它不是一部分的问题。我只想知道如何打开我有权限的文件夹中的特定文件。
Code for selecting folder
正如 blackapps 所指出的,去掉这些标志,因为它们在这种情况下是无用的。
I think the problem is on the last bit of code
正确。您无法手动创建有效文档 Uri
值。
but i really dont know what else to try
你要的不靠谱。您正在假设树中文档的显示名称可能与实际情况不符。但是,如果您愿意忍受兼容性问题,您可以这样做:
第 1 步:调用 DocumentFile.fromTreeUri()
,传入您从 onActivityResult()
获得的树 Uri
,为树 [=25= 提供 DocumentFile
]
第 2 步:在那个 DocumentFile
上调用 listFiles()
来为您提供一个 DocumentFile
对象数组,表示该树根
的内容
第 3 步:使用 getName()
和 isFile()
将该数组过滤为与所需命名方案匹配的子集
第 4 步:对于匹配的文件,调用 getUri()
获取这些文件的 Uri
,您可以将其传递给您最喜欢的 image-loading 图书馆
我正在尝试从特定文件夹中获取所有图像以显示在回收站视图中,但无论如何,我都收到了 SecurityException。
我目前正在按照以下方式进行操作:
selecting 文件夹的代码
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
lastRequest = REQUEST_IMAGENS;
startActivityForResult(i, REQUEST_IMAGENS);
onActivityResult
getContentResolver().takePersistableUriPermission(data.getData(),data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
并获取每个单独的位图(这部分特别是我尝试了许多不同的变体,但结果都相同)
BitmapFactory.decodeStream(xContext.getContentResolver().openInputStream(Uri.parse(stringUri + "%3A" + (archiveName + ".png"))));
我认为问题出在最后一段代码上,但我真的不知道还能尝试什么。
我得到的异常是:
java.lang.SecurityException: Permission Denial: reading com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/tree/primary%3ADownload%2FSaurus%20-%20Cadastro%20-%20Imagens%3A2171.png from pid=13239, uid=10425 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
我已经使用 getPersistedUriPermissions 检索了持久化权限,它包含以下 uri:
content://com.android.externalstorage.documents/tree/primary%3ADownload%2FSaurus%20-%20Cadastro%20-%20Imagens
我几乎可以肯定我不能像我一样手动附加文件名,但我不知道我必须做什么。
我读过其他帖子,有很多不同的答案,但 none 有效,我尝试了几乎所有我能找到的东西。
感谢任何帮助,谢谢。
已编辑:
问题是我只希望用户 select 文件夹,而不是所有图像,然后我将在文件夹中搜索我想要的图像,在我省略的循环中,因为它不是一部分的问题。我只想知道如何打开我有权限的文件夹中的特定文件。
Code for selecting folder
正如 blackapps 所指出的,去掉这些标志,因为它们在这种情况下是无用的。
I think the problem is on the last bit of code
正确。您无法手动创建有效文档 Uri
值。
but i really dont know what else to try
你要的不靠谱。您正在假设树中文档的显示名称可能与实际情况不符。但是,如果您愿意忍受兼容性问题,您可以这样做:
第 1 步:调用 DocumentFile.fromTreeUri()
,传入您从 onActivityResult()
获得的树 Uri
,为树 [=25= 提供 DocumentFile
]
第 2 步:在那个 DocumentFile
上调用 listFiles()
来为您提供一个 DocumentFile
对象数组,表示该树根
第 3 步:使用 getName()
和 isFile()
将该数组过滤为与所需命名方案匹配的子集
第 4 步:对于匹配的文件,调用 getUri()
获取这些文件的 Uri
,您可以将其传递给您最喜欢的 image-loading 图书馆