Первое, что стоит упомянуть, ответы на вопрос здесь не помогают.
Исходный код выглядит следующим образом:
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));
FileProvider.getUriForFile
isвыдает исключение и вот трассировка стека:
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)
В 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>
Содержимое file_paths.xml
isследующее:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="input_files" path="." />
<external-path name="output_files" path="MyAppName/" />
</paths>
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);
}
rootPath
оценивается как /storage/sdcard
, что также является точным значением path
, поэтому неудивительно, что исключениевыброшены.
Что я делаю не так?
ОБНОВЛЕНИЕ:
Как указано ниже, переданный java.io.File
не должен быть каталогом. Документы неоднозначны и никогда не говорят этого явно.Обходной путь должен был бы создать URI «вручную».Таким образом,
intent.setData(FileProvider.getUriForFile(this, authority, file));
следует заменить на:
intent.setData(Uri.parse("content://" + file.getAbsolutePath()));