FileProvider "Failed to find configured root" 异常
FileProvider "Failed to find configured root" exception
这些 FileProvider 中的一个又一个迷失了灵魂......我已经在这个问题上工作了一天多了,看来我遗漏了一些重要的东西。如有任何帮助,我们将不胜感激!
我正在尝试使用 FileProvider 发送带附件的电子邮件。
我的AndroidManifest.xml部分:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="todolistj.todolist.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="lists_to_send" path="export/"/>
</paths>
正在创建附件:
String content = "hello world";
File file;
FileOutputStream outputStream;
try {
File dir = context.getExternalFilesDir("export");
if(!dir.exists()) dir.mkdir();
file = new File(dir, "MyCache");
if (file.exists ()) file.delete ();
outputStream = new FileOutputStream(file);
outputStream.write(content.getBytes());
outputStream.close();
return file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
和 Uri 创建:
File readF = new File(fullFileName);
Uri uri = FileProvider.getUriForFile(this, "todolistj.todolist.fileprovider", readF);
其中 fullFileName
是文件创建代码段中返回的值。
在 Uri 创建行我得到异常:
...
Caused by: java.lang.IllegalArgumentException: Failed to find configured
root that contains /storage/emulated/0/Android/data/todolistj.todolist/files/export/MyCache
...
正如此处的文档 (https://developer.android.com/reference/android/support/v4/content/FileProvider.html) 所述:
< external-files-path name="name" path="path" />
Represents files in the root of your app's external storage area. The root path of this subdirectory is the same as the value returned
by Context#getExternalFilesDir(String)
Context.getExternalFilesDir(null).
所以我的 xml 的外部文件路径似乎与我正在使用的 context.getExternalFilesDir
方法匹配。
这两个地方我都有 "export" 文件夹。当局似乎匹配......我的问题可能是什么。我找不到找到和打印 FileProvider 的 "configured root"
的方法
File photoFile =new File(fullFileName);
if (photoFile != null) {
Uri photoURI =FileProvider.getUriForFile(MainActivity.this(your activity name),
BuildConfig.APPLICATION_ID + ".provider", photoFile);
}
如果您像这样创建 Uri,它可能适合您。
我似乎找到了解决方法或修复方法。
将我在 xml 中使用的根目录类型从 external-files-path
更改为 cache-path
,并从 context.getExternalFilesDir("export");
更改为 File dir = new File(context.getCacheDir(), "export");
以获取创建文件的文件夹。
并且我成功附加了文件。请注意,在 FileProvider class 的 FileProvider.java 中,我发现了以下用于构建 Uris 的代码:
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);
}
好像只支持以下 4 个文件夹:TAG_ROOT_PATH、TAG_FILES_PATH、TAG_CACHE_PATH、TAG_EXTERNAL。没有TAG_EXTERNAL_FILES之类的东西,所以这看起来像是文档和实现之间的不匹配,实际上不支持匹配getExternalFilesDir
方法的external-files-path
。
有一些解决方法:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="logs" path="../logs/" />
<!-- use ".." to get files from app's root data dir -->
</paths>
提供来自/data/data/xxx.xxx.xxx/
的文件
在我的例子中是 /data/data/xxx.xxx.xxx/logs/
这些 FileProvider 中的一个又一个迷失了灵魂......我已经在这个问题上工作了一天多了,看来我遗漏了一些重要的东西。如有任何帮助,我们将不胜感激!
我正在尝试使用 FileProvider 发送带附件的电子邮件。
我的AndroidManifest.xml部分:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="todolistj.todolist.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="lists_to_send" path="export/"/>
</paths>
正在创建附件:
String content = "hello world";
File file;
FileOutputStream outputStream;
try {
File dir = context.getExternalFilesDir("export");
if(!dir.exists()) dir.mkdir();
file = new File(dir, "MyCache");
if (file.exists ()) file.delete ();
outputStream = new FileOutputStream(file);
outputStream.write(content.getBytes());
outputStream.close();
return file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
和 Uri 创建:
File readF = new File(fullFileName);
Uri uri = FileProvider.getUriForFile(this, "todolistj.todolist.fileprovider", readF);
其中 fullFileName
是文件创建代码段中返回的值。
在 Uri 创建行我得到异常:
...
Caused by: java.lang.IllegalArgumentException: Failed to find configured
root that contains /storage/emulated/0/Android/data/todolistj.todolist/files/export/MyCache
...
正如此处的文档 (https://developer.android.com/reference/android/support/v4/content/FileProvider.html) 所述:
< external-files-path name="name" path="path" /> Represents files in the root of your app's external storage area. The root path of this subdirectory is the same as the value returned by Context#getExternalFilesDir(String) Context.getExternalFilesDir(null).
所以我的 xml 的外部文件路径似乎与我正在使用的 context.getExternalFilesDir
方法匹配。
这两个地方我都有 "export" 文件夹。当局似乎匹配......我的问题可能是什么。我找不到找到和打印 FileProvider 的 "configured root"
File photoFile =new File(fullFileName);
if (photoFile != null) {
Uri photoURI =FileProvider.getUriForFile(MainActivity.this(your activity name),
BuildConfig.APPLICATION_ID + ".provider", photoFile);
}
如果您像这样创建 Uri,它可能适合您。
我似乎找到了解决方法或修复方法。
将我在 xml 中使用的根目录类型从 external-files-path
更改为 cache-path
,并从 context.getExternalFilesDir("export");
更改为 File dir = new File(context.getCacheDir(), "export");
以获取创建文件的文件夹。
并且我成功附加了文件。请注意,在 FileProvider class 的 FileProvider.java 中,我发现了以下用于构建 Uris 的代码:
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);
}
好像只支持以下 4 个文件夹:TAG_ROOT_PATH、TAG_FILES_PATH、TAG_CACHE_PATH、TAG_EXTERNAL。没有TAG_EXTERNAL_FILES之类的东西,所以这看起来像是文档和实现之间的不匹配,实际上不支持匹配getExternalFilesDir
方法的external-files-path
。
有一些解决方法:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="logs" path="../logs/" />
<!-- use ".." to get files from app's root data dir -->
</paths>
提供来自/data/data/xxx.xxx.xxx/
的文件
在我的例子中是 /data/data/xxx.xxx.xxx/logs/