FileProvider.getUriForFile 抛出 StringIndexOutOfBoundsException

Vik*_*šan 7 java android android-intent android-fileprovider

首先要提到的是,这里问题的答案没有帮助。

源代码如下所示:

Intent intent    = new Intent("com.mycompany.action.PICK_FILE");
String authority = "com.mycompany.fileprovider";
File   file      = Environment.getExternalStorageDirectory();

intent.setData(FileProvider.getUriForFile(this, authority, file));
Run Code Online (Sandbox Code Playgroud)

FileProvider.getUriForFile抛出异常,这是堆栈跟踪:

java.lang.StringIndexOutOfBoundsException: length=15; index=16
at java.lang.String.indexAndLength(String.java:500)
at java.lang.String.substring(String.java:1313)
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:687)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:377)
Run Code Online (Sandbox Code Playgroud)

在标签AndroidManifest.xml内部application我添加了以下内容:

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.mycompany.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" 
            />
        </provider>
Run Code Online (Sandbox Code Playgroud)

内容file_paths.xml如下:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="input_files"  path="." />
    <external-path name="output_files" path="MyAppName/" />
</paths>
Run Code Online (Sandbox Code Playgroud)

output_files在此上下文中不使用路径。

我已经通过运行调试器FileProvider.SimplePathStrategy.getUriForFile()。相关代码片段如下(第683-688行):

            final String rootPath = mostSpecific.getValue().getPath();
            if (rootPath.endsWith("/")) {
                path = path.substring(rootPath.length());
            } else {
                path = path.substring(rootPath.length() + 1);
            }
Run Code Online (Sandbox Code Playgroud)

rootPath的计算结果/storage/sdcard也是 的精确值path,因此抛出异常也就不足为奇了。

我究竟做错了什么?

更新:

如下所示,传递的java.io.File不应是目录。文档含糊不清,从未明确说明。解决方法是“手动”创建 uri。因此

intent.setData(FileProvider.getUriForFile(this, authority, file));
Run Code Online (Sandbox Code Playgroud)

应替换为:

intent.setData(Uri.parse("content://" + file.getAbsolutePath()));
Run Code Online (Sandbox Code Playgroud)

Dmy*_*nov 3

getUriForFile 的第三个参数应该是带有文件名的文件路径。这是一个文档,请阅读它