是否可以从 DocumentFile 获取常规文件?
Posted
技术标签:
【中文标题】是否可以从 DocumentFile 获取常规文件?【英文标题】:Is it possible to get a regular File from DocumentFile? 【发布时间】:2017-01-27 09:51:59 【问题描述】:对于android,下面的代码返回一个Uri,可以用来创建一个目录对应的DocumentFile。
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_CUSTOM_FOLDER);
由于库的许多方法都需要一个参数是 java.io.File,我想知道是否可以从 DocumentFile 中获取 java.io.File。
例如,返回的文档树 Uri treeUri 如下:
treeUri.getPath():/tree/primary:DCIM/deeper/evendeeper
treeUri.toString(): content://com.android.externalstorage.documents/tree/primary%3ADCIM%2Fdeeper%2Fevendeeper
以下是 ADM 中显示的目录:
【问题讨论】:
【参考方案1】:是的,你可以。对于 API 30+,您需要 full storage access。而对于 API 28-,您只需要 Manifest.permission.READ_EXTERNAL_STORAGE
。
使用SimpleStorage,您可以将DocumentFile
转换为java.io.File
:
val file: File? = documentFile.toRawFile(context)?.takeIf it.canRead()
【讨论】:
【参考方案2】:是的,但地址可能是 ASCII 格式,您必须将其转换为 UTF-8 以避免像“%2F”这样的文本字符串。我推荐使用 "val decoded = URLDecoder.decode (input," utf-8 ")"
【讨论】:
【参考方案3】:I am wondering if one can get a java.io.File from a DocumentFile.
是的,大多数情况下你可以。如果用户从主存储或辅助存储中选择“文件”,则可以,因为内容方案与文件或目录的文件路径之间存在一对一的关系。
但如果你真的需要 java.io.File 你最好使用文件选择器。
[更新]
content://com.android.externalstorage.documents/tree/primar%3ADCIM%2Fdeeper%2Fevendeeper
content://com.android.externalstorage.documents/tree/primary:DCIM/deeper/evendeeper
如果是这样,例如对应于
/storage/emulated/0/DCIM/deeper/evendeeper.
和
content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fcom.aaaa.org%2Ffiles%2Fafile.txt
content://com.android.externalstorage.documents/tree/primary:Android/com.aaaa.org/files/afile.txt
转化
/storage/emulated/0/Android/com.aaa.org/files/afile.txt
如果你知道一个你就知道他们都知道:这是一对一的关系。
您唯一需要做的就是将content://com.android.externalstorage.documents/tree/primary:
替换为/storage/emulated/0/
这将问题减少到确定/storage/emulated/0/
。
为此,您必须让用户为所选内容方案选择文件系统路径的根目录。如果无法选择,通常可以通过设备上的文件资源管理器应用程序找到。最后你可以让输入的路径。
与Android SAF (Storage Access FrameWork): Get particular file Uri from TreeUri 或带有标签storage-acccess-framework
的其他帖子中的完全相反。
【讨论】:
感谢您的帮助。如何将 DocumentFile 的实例转换为 java.io.File? 请将所选文档树的 uri.toSting 与同一目录的文件系统路径一起发布。比较。 好的。但是您没有发布相应的文件系统路径。我也是这么求的。 /storage/emulated/0/DCIM 或 /sdcard/DCIM 之类的东西。 您能告诉我如何从 Uri 中获取文件路径吗? 错误的问题。你应该先回答我的问题。重复:该 DCIM 目录的等效文件系统路径是什么?有几个可能性要找出来。你不能使用它的uri。【参考方案4】:以下代码返回一个Uri,可以用来创建一个目录对应的DocumentFile
不,它没有。它返回一个Uri
,可用于创建与文档树相对应的DocumentFile
。它不需要代表文件系统上的目录。文档树的表示位置和方式取决于用户选择的DocumentsProvider
。该提供者可以做任何它想代表树的事情(例如,使用数据库,使用对服务器的 REST 调用)。
我想知道是否可以从 DocumentFile 中获取 java.io.File。
没有,因为没有文件。
【讨论】:
非常感谢您的及时回答。看起来我们必须采取其他方式 - 更改方法以使用效率低下的 DocumentFile 而不是 File。以上是关于是否可以从 DocumentFile 获取常规文件?的主要内容,如果未能解决你的问题,请参考以下文章
SAF DocumentFile - 检查路径是不是存在而不在每个文件夹级别创建每个 DocumentFile
正确删除 DocumentFile(尊重 MediaStore)