【问题标题】:Is it possible to get a regular File from DocumentFile?是否可以从 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 中显示的目录:

【问题讨论】:

    标签: android android-file storage-access-framework documentfile


    【解决方案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/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 的其他帖子中的完全相反。

        【讨论】:

        • 感谢您的帮助。如何将 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。
        猜你喜欢
        • 1970-01-01
        • 2012-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-02
        • 2019-01-23
        • 2018-01-16
        • 1970-01-01
        相关资源
        最近更新 更多