是否可以从 DocumentFile 获取常规文件?

Is it possible to get a regular File from DocumentFile?

对于Android,下面的代码returns一个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中显示的目录如下:

the following code returns a Uri that can be used to create DocumentFile corresponding to a directory

不,不是。它 returns 一个 Uri 可用于创建一个 DocumentFile 对应于文档树。不需要它代表文件系统上的目录。文档树的表示位置和方式取决于用户选择的 DocumentsProvider。该提供者可以做任何它想做的事情来表示树(例如,使用数据库,使用对服务器的 REST 调用)。

I am wondering if one can get a java.io.File from a DocumentFile.

没有,因为没有文件。

I am wondering if one can get a java.io.File from a DocumentFile.

是的,大多数情况下你可以。如果用户从主存储或辅助存储中选择 'file',则可以,因为内容方案与文件或目录的文件路径之间存在一对一的关系。

但是如果你真的需要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/afil‌​e.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 的帖子完全相反。

是的,但地址可能是 ASCII 格式,您必须将其转换为 UTF-8 以避免像“%2F”这样的文本字符串。我推荐使用“val decoded = URLDecoder.decode (input,”utf-8”)”

是的,你可以。对于 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() }