非常感谢您的任何帮助。
谢谢。
我按照@Gubatron的建议在我的XML中添加了这个根路径,并且它确实起作用了。
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
<root-path name="external_files" path="/storage/" />
</paths>
让我们来看一下 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;
}
FileProvider
接受root-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>
,因此在未来可能会更改。
FileProvider
不支持第二个外部存储(例如可移动的SD卡)。这在Android 7及以上版本中更成为问题,因为您不能再使用file://
URI。
我已经在这里提交了一个错误报告。
</paths> - Gubatron从Android 4.4开始,普通应用程序不允许访问辅助外部存储设备,即SD卡,除非在其特定于包的目录中,即使您已请求WRITE_EXTERNAL_STORAGE权限。
WRITE_EXTERNAL_STORAGE权限只能授予对设备上的主要外部存储的写访问权限。应用程序不得被允许写入辅助外部存储设备,除非使用合成权限允许在其特定于包的目录中进行写入。以这种方式限制写入可以确保系统在卸载应用程序时清理文件。
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/
开头,而文件路径则以
/storage/
开头。因此,我们需要添加以下行:
<root-path name="external_files" path="/storage/" />
在
@xml/provider_paths.xml