ActivityResultContracts.OpenDocument 可以 return 一个非全功能的 URI

ActivityResultContracts.OpenDocument can return a non-full-featured URI

ActivityResultContracts.OpenDocument can be "opaque" (I don't know a better term) in a sense that you can't write to the associated file using it (openOutputStream 返回的 URI 抛出 IllegalArgumentException 消息“媒体是只读的”),您无法确定其父目录等,因为它的形式为例如“/document/image:821286”。不过,我可以使用它读取文件数据,并不是 OpenDocument 启动器返回的所有 URI 都是“不透明的”。

我知道我确实拥有所有这些文件所需的所有访问权限,因为如果 ActivityResultContracts.CreateDocument 返回同一文件,则返回的 URI 永远不会“不透明”,因此您可以写入它,获取包含目录等。在这种情况下,URI 类似于“/document/primary:DCIM/Camera/IMG_20211007_101132.jpg”。

我确实获得了 WRITE_EXTERNAL_STORAGE 许可,并且正在 Android 9.

上进行测试

我正在寻找一种方法来始终从 OpenDocument 启动器获取“透明”URI 或将“不透明”URI 转换为“透明”URI;请在下面写下如何完成其​​中任何一项。

in a sense that you can't write to the associated file using it (openOutputStream throws IllegalArgumentException with message "Media is read-only")

这是存储访问框架的一个不幸限制:poorly-written 文档提供者可以选择不允许 read-write 访问内容,并且 we have no means of specifying that we only want writeable documents。在这些情况下我们必须优雅地失败。

because if the same file is returned by ActivityResultContracts.CreateDocument the returned URI is never "opaque"

事实并非如此。您测试了众多文档提供者中的一个,不幸的是该文档提供者泄露了信息。不要求任何给定设备具有以这种方式运行的文档提供程序,也不要求用户使用此类文档提供程序。

文档提供者不必使用 publicly-accessible 文件系统路径,更不用说告诉您这些路径是什么了。欢迎文档提供者将文档存储在网络服务器、云存储提供商(例如,Google 驱动器)、加密数据存储等上

I am looking for a way to either always get "transperent" URIs from OpenDocument launcher or to convert "opaque" to "transparent" URI; please write below how to accomplish either of those.

那是不可能的。