6

I have created an app, that creates gpx files. Everything is working fine except for the sharing. Therefore I have created a File Provider. You can see it's configuration below. The Provider is working fine on my android device running Android 8.0.0 but on a friends Huawei (6.0) it is not working

Fatal Exception: java.lang.IllegalArgumentException
Failed to find configured root that contains /storage/8737-15E4/Android/data/XXX/cache/20171009_171900.gpx

Provider in Manifest:

<provider
        android:name=".GenericFileProvider"
        android:authorities="com.package.test.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:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="external-files" path="/" />
<external-cache-path name="cache-files" path="/" />
</paths>

Usage in Code:

File gpxFile = new File(context.getExternalCacheDir(), "20171009_171900.gpx");    
Uri gpxContentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", gpxFile);

        Intent gpxIntent = new Intent(Intent.ACTION_SEND);
        gpxIntent.setType("text/gpx");

        gpxIntent.putExtra(Intent.EXTRA_STREAM, gpxContentUri);

        Intent programChooser = Intent.createChooser(gpxIntent, context.getString(R.string.select_app_to_share));
        programChooser.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

        activityForDialog.startActivity(programChooser);

I hope someone can help me to find the bug that causes the app to crash on some devices...

Jared
  • 2,999
  • 1
  • 28
  • 39
Mojo
  • 377
  • 6
  • 18
  • The permission for the storage is set like this: – Mojo Oct 10 '17 at 18:44
  • That filesystem path looks more like removable storage than external storage. However, I would expect both `FileProvider` and your own code to get the same strange value for `getExternalCacheDir()`, and so they should be consistent. Your symptoms would fit if somehow `FileProvider` were getting a more traditional value for `getExternalCacheDir()` (e.g., `/storage/emulated/0/Android/data/XXX/cache/20171009_171900.gpx`) while your code here is not. – CommonsWare Oct 10 '17 at 18:45
  • Okay. so should I extend the file-provider paths? – Mojo Oct 10 '17 at 18:48
  • `FileProvider` does not support removable storage as an alternative to things like ``. I just can't explain why `FileProvider` might apparently get one value for `getExternalCacheDir()` and why your code would get another. What exactly is `context` in your code? Where is this `Context` coming from? – CommonsWare Oct 10 '17 at 18:51
  • The Context is generate by calling Activity activity = Activity.this; Context context = activity.getApplicationContext(); I think this should work... – Mojo Oct 10 '17 at 18:54
  • 1
    Yes -- in fact, I was going to suggest that if you were using something else. I cannot explain the symptoms. A workaround would be to catch the exception and use `Uri.forFile()` instead on Android 6.0 and older devices. – CommonsWare Oct 10 '17 at 18:56
  • Okay thank you. So I will catch this exception and in the catch block I will call Uri.forFile(), right? – Mojo Oct 10 '17 at 18:59
  • Correct. This won't work on Android 7.0+ without some more work, but hopefully you will not run into this on Android 7.0+ devices. So, you use `FileProvider` where you can, falling back to `Uri.forFile()` where `FileProvider` does not like the device (for whatever reason). – CommonsWare Oct 10 '17 at 19:03
  • Many thanks for your quick help. I will try it ;) – Mojo Oct 10 '17 at 19:06
  • @Mojo Did you find a fix for this, same thing happens to a customer on a Huawei running android 7. It has not crashed on any other device that I've tested. – Procedurally Generated Dec 18 '17 at 12:32
  • @Varun no I'm sorry I haven't. But I am now using the work around CommonsWare mentioned and this works fine ;) – Mojo Jan 04 '18 at 10:13
  • I'd like to add that I'm also having this issue where it works for everybody else, but specifically with the Huawei P8 Lite (2017) (running Android 7.0), it throws this error. I'm going to try to check on it more and see if there is another solution. – Jared Jan 26 '18 at 01:58
  • Happened only once so far in my app on a Huawei Honor 7A Pro. But Android 8. But really seems to be connected to Huawei – Al Cabone Dec 06 '18 at 15:29
  • Hi, i'm facing the same issue on a Huawei P30 lite with Android 10. The code works so far on every device i have tested it. Only on the Huawei P30 lite i'm getting this error. Have you found any solution to this? – Thomas Meinhart Jan 13 '20 at 13:22

1 Answers1

4

Modify your "Usage in Code:" and replace the 2nd line

Uri gpxContentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", gpxFile);

with this:

Uri gpxContentUri;
try {
    gpxContentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", gpxFile);
} catch (IllegalArgumentException e) {
    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());
    gpxContentUri = Uri.fromFile(gpxFile);
}

Note: This error only seemed to be thrown for me on the "Huawei P8 Lite (PRA-LX1)" running Android 7.0, and the Mojo said it only happened on his friend's Huawei (6.0). I'm starting to think this is only an issue with those phones, but it's good to have a workaround.

Jared
  • 2,999
  • 1
  • 28
  • 39
  • What's `uriList`? – EpicPandaForce Feb 12 '18 at 23:18
  • 1
    @EpicPandaForce first of all, awesome name, second of all, thanks for catching that! uriList wasn't supposed to be there, however, if anybody is interested, I personally use this code with this: `ArrayList uriList = new ArrayList();` which i then send to a send intent (`ACTION_SEND_MULTIPLE`) I have corrected the answer, thanks again! – Jared Feb 13 '18 at 23:34