FileProvider.getUriForFile is causing StringIndexOutOfBoundsException
Asked Answered
S

2

5

I have updated my project to implement Providers. The whole implementations seem right, but I am receiving a StringIndexOutOfBoundsException exception inside FileProvider class.

In my case, an Intent is created, in which, the user will choose between get an image from his library or take a new photo.

That is where one of my Intents is created, to after, include in a list, to create a chooser.

    File file = getTempFile(context);
    if (file != null) {
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        takePhotoIntent.putExtra("return-data", true);
        takePhotoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                FileProvider.getUriForFile(context,                        // line 43
                        BuildConfig.APPLICATION_ID.concat(".fileprovider"),
                        file));
        intentList = addIntentsToList(context, intentList, takePhotoIntent);
    }

getTempFile method:

private static File getTempFile(Context context) {
    File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME);
    if (imageFile.getParentFile().mkdirs()) {
        return imageFile;
    } else {
        return null;
    }
}

Exceptions that are thrown:

java.lang.StringIndexOutOfBoundsException: length=86; index=87
     at java.lang.String.substring(String.java:1939)
     at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:728)
     at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:404)
     at com.project.helper.ImagePicker.getPickImageIntent(ImagePicker.java:43)

How do I proceed in this situation? Maybe it is a bug in this version of Provider? To follow, some more information about my project:

Manifest file:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.project.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 file:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="images" path="Android/data/com.project/cache/tempImage" />
</paths>

buildToolsVersion '27.0.2'

Stipulation answered 21/12, 2017 at 18:58 Comment(0)
S
3

Replace:

<external-path name="images" path="Android/data/com.project/cache/tempImage" />

with:

<external-cache-path name="images" path="." />

First, that will be more reliable, as your current implementation makes assumptions about where getExternalCacheDir() points. Second, path needs to point to a directory, not a file, and my guess is that this is where things are going sideways.

Smoothspoken answered 21/12, 2017 at 19:3 Comment(4)
Changing to external-cache-path with no path parameter causes path' attribute should be definedStipulation
@GuilhermeFGL: Hmmm... I thought that was optional. Try path=".". Or, put your image in some subdirectory off of getExternalCacheDir() and put that directory name in path.Smoothspoken
<external-cache-path name="images" path="." /> solved my problem. Didn't get why the exception, though.Stipulation
@GuilhermeFGL: The code there is comparing the fully-qualified path to the file to what was supposed to be a directory. In your case, you were pointing to a file, and that was breaking their algorithm.Smoothspoken
S
2

You have to change the xml in this way:

<external-path name="images" path="." />
Semiaquatic answered 21/12, 2017 at 19:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.