如何将文件路径转换为treeUri

问题描述

在我的应用程序中,我有一个常规的设置,用户可以在其Android设备上选择视频目录,并且在该目录中找到的视频将在应用程序中的某个位置播放。现在,当用户本人通过“首选项”进行操作时,我正在打开ACTION_OPEN_DOCUMENT_TREE,而返回的Uri是treeUri,后来我在我的视频活动中将其与DocumentsContract.buildChildDocumentsUriUsingTree一起使用。这部分完全正常,可以正常工作。

但是,由于此应用程序将在企业中使用,因此我有一个要求,即IT部门可以提交我完全控制在应用程序外部目录中的外部xml文件,您作为用户可以设置所有选项在应用程序本身中,并且如果该文件存在,则需要在SharedPreferences中实现这些选项。除了该视频目录之外,我还可以从该外部xml文件实现所有设置。我以为用户可以在xml中提供常规路径,例如<setting key="video_folder">/sdcard/Movies</setting>,然后在应用程序中对其进行解析,从路径中获取treeUri,并将其保存在SharedPreferences中以备后用。任何想法是否可行,或者应该采用其他方法? 我在下面尝试过这种方法:

public static Uri[] getSafUris (Context context,File file) {

        Uri[] uri = new Uri[2];
        String scheme = "content";
        String authority = "com.android.externalstorage.documents";

        // Separate each element of the File path
        // File format: "/storage/XXXX-XXXX/sub-folder1/sub-folder2..../filename"
        // (XXXX-XXXX is external removable number
        String[] ele = file.getPath().split(File.separator);
        //  ele[0] = not used (empty)
        //  ele[1] = not used (storage name)
        //  ele[2] = storage number
        //  ele[3 to (n-1)] = folders
        //  ele[n] = file name

        // Construct folders strings using SAF format
        StringBuilder folders = new StringBuilder();
        if (ele.length > 4) {
            folders.append(ele[3]);
            for (int i = 4; i < ele.length - 1; ++i) folders.append("%2F").append(ele[i]);
        }

        String common = ele[2] + "%3A" + folders.toString();

        // Construct TREE Uri
        Uri.Builder builder = new Uri.Builder();
        builder.scheme(scheme);
        builder.authority(authority);
        builder.encodedPath("/tree/" + common);
        uri[0] = builder.build();

        // Construct DOCUMENT Uri
        builder = new Uri.Builder();
        builder.scheme(scheme);
        builder.authority(authority);
        if (ele.length > 4) common = common + "%2F";
        builder.encodedPath("/document/" + common + file.getName());
        uri[1] = builder.build();

        return uri;
    }

但这给了我

Permission Denial: reading com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/tree/Movies%3A/document/Movies%3A/children from pid=28318,uid=10157 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

解决方法

为了绕过SAF,我必须完全重新排列播放视频的逻辑,以便从常规文件:// uri读取它们。简而言之,我的问题是,如果您没有从ACTION_OPEN_DOCUMENT,ACTION_OPEN_DOCUMENT_TREE和类似的API中获取树URI,则有任何可能的方式来获取该树URI的许可。据我所知,这是不可能的(甚至没有向用户提供任何类型的运行时权限)。如果有人认为有这种可能性,请告诉我。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...