6

例如,我正在使用 FileProvider 将我的内部文件公开给图库。为了使其更加统一,我还将外部文件放入提供程序(通过外部路径),但对于可移动 sd 卡中的文件,它不起作用。说类似该文件夹的内容是未经授权的。

任何帮助将不胜感激。

谢谢

4

6 回答 6

25

我按照@Gubatron 在我的 XML 中的建议添加了这个根路径,它可以工作。

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
    <root-path name="external_files" path="/storage/" />
</paths>
于 2017-06-13T05:04:03.207 回答
7

让我们看一下FileProvider代码:

    private static PathStrategy parsePathStrategy(Context context, String authority)
        ...
        int type;
        while ((type = in.next()) != END_DOCUMENT) {
            if (type == START_TAG) {
                final String tag = in.getName();
                final String name = in.getAttributeValue(null, ATTR_NAME);
                String path = in.getAttributeValue(null, ATTR_PATH);
                File target = null;
                if (TAG_ROOT_PATH.equals(tag)) {
                    target = buildPath(DEVICE_ROOT, path);
                } else if (TAG_FILES_PATH.equals(tag)) {
                    target = buildPath(context.getFilesDir(), path);
                } else if (TAG_CACHE_PATH.equals(tag)) {
                    target = buildPath(context.getCacheDir(), path);
                } else if (TAG_EXTERNAL.equals(tag)) {
                    target = buildPath(Environment.getExternalStorageDirectory(), path);
                }
                if (target != null) {
                    strat.addRoot(name, target);
                }
            }
        }
        return strat;
    }

FileProviderroot-path在标签(DEVICE_ROOT 常量)的帮助下接受目录的绝对路径。因此,只需将绝对路径添加到辅助外部磁盘中的文件夹,如下所示:

<root-path path="/storage/extSdCard/Android/data/com.edufii/files/image/" name="image-ext2" />
<root-path path="/storage/extSdCard/Android/data/com.edufii/files/video/" name="video-ext2" />
<root-path path="/storage/extSdCard/Android/data/com.edufii/files/datafile/" name="datafile-ext2" />
<root-path path="/storage/extSdCard/Android/data/com.edufii/files/audio/" name="audio-ext2" />

请注意官方文档没有说明任何关于的内容<root-path>,因此将来可能会更改。

于 2016-06-14T09:18:21.850 回答
2

从 android 4.4 开始,普通应用程序不允许访问辅助外部存储设备,即 sd 卡,除非在它们的包特定目录中,即使您已请求 WRITE_EXTERNAL_STORAGE 权限。

WRITE_EXTERNAL_STORAGE 权限只能授予对设备上主要外部存储的写访问权限。不允许应用程序写入辅助外部存储设备,除非在合成权限允许的特定包目录中。以这种方式限制写入可确保系统可以在卸载应用程序时清理文件。

https://source.android.com/devices/storage/

于 2015-09-01T14:13:30.510 回答
1

FileProvider不支持辅助外部存储(如可移动 sd 卡)。这在 Android 7 及更高版本中更是一个问题 - 因为您不能再使用file://uri。

我已经在这里发布了错误报告。

于 2016-11-20T09:38:00.860 回答
0

访问外部 sdcard 。第一次调用uri.getEncodedPath() 获取编码路径

" /external_files/3161-3330/WhatsApp/Media/WhatsApp%20Documents/All%20Currency.pdf "

然后使用以下逻辑获取外部存储的文件路径

public String getFilePath(){
    if (isKitKat && DocumentsContract.isDocumentUri(mContext, uri)) {
                // ExternalStorageProvider
                if (com.android.externalstorage.documents.equals(uri.getAuthority())) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
    
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    } else {
                        return "/storage" + "/" + split[0] + "/" + split[1];
                    }
               }
    }
}

getFilePath()会给 :

/storage/emulated/0/3161-3330/WhatsApp/Media/WhatsApp Documents/All Currency.pdf

uri 路径从哪里开始

/external_files/

并且文件路径以

/贮存/

因此,我们必须添加以下行

 <root-path name="external_files" path="/storage/" />

@xml/provider_paths.xml

于 2019-07-25T10:48:11.030 回答
0

我不完全确定为什么,但root-path对我不起作用。此外,它没有记录在案,所以它可能会在某个时候突然消失。所以我最终使用了以下内容。

<external-files-path name="external_files_path" path="/"/>

File file = new File(getActivity().getExternalFilesDir(null), "hello.txt");

该文件存储在/storage/emulated/0/Android/data/MY_APP/files/hello.txt,这是我的应用程序自己在 SD 卡中的存储位置。

于 2018-02-14T01:38:14.870 回答