22

I'm trying to set up a fileprovider for sharing file. My files are saved in a folder "AppName" in the external storage (same level as Android, Movies and Pictures folders).

Here is my file provider config :

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.mydomain.appname.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"/>
</provider>

and the file_paths.xml :

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

When i try to access my file with :

Uri fileUri = FileProvider.getUriForFile(activity, "com.mydomain.appname.fileprovider",
            new File("/storage/emulated/0/AppName/IMG_20160419_095211.jpg"));

It returns an error: java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/AppName/IMG_20160419_095211.jpg at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:678) at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:377)

It worked fine before when I was using built-in directory like Pictures or Movies, my file_paths.xml was define like this :

<external-path name="photos" path="Pictures" />
<external-path name="videos" path="Movies" />

But now I want to store my file in my own folder. Did I miss something with the FileProvider config ?

budgw
  • 710
  • 1
  • 5
  • 13
  • Perhaps the problem is with the hardcoded path in your `File` constructor. Use `new File(Environment.getExternalStorageDirectory(), "AppName/IMG_20160419_095211.jpg")` and see if you have better luck. – CommonsWare May 06 '16 at 14:27
  • I just try that and it does not work – budgw May 06 '16 at 14:32

8 Answers8

38
<files-path name="name" path="path" />  

Represents files in the files/ subdirectory of your app's internal storage area. This subdirectory is the same as the value returned by Context.getFilesDir().

<external-path name="name" path="path" />

Represents files in the root of the external storage area. The root path of this subdirectory is the same as the value returned by Environment.getExternalStorageDirectory().

<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).

for more details please check Android's doc of FileProvider. some configuration like following picture,com.view.asim.enterprise is my package name. enter image description here

aolphn
  • 2,950
  • 2
  • 21
  • 30
9

First, I know this is an old post but it's the closest question posted that was similar to my problem so I'll post my solution.

The reason for that error is because the path you're supplying in the provider file is either

  • a) Spelled incorrectly and doesn't exist in the external-path
  • b) Using the /storage/emulated/0 absolute path

It returns Failed to find configured root that contains ... because it can't find that folder. So make sure you write only the directory you want to share, and ensure it's spelled correctly. Remember that when you declare external-path it is the equivelant of calling Enviornment.getExternalStorageDirectory() Since you write the name of the directory when you create your file, you don't need to provide a path in your provider file as all it does is mask whatever value is in the path with the name.

So your provider path would be: <external-path name="my_files" />

and your code would be:

File file = new File(new File(Environment.getExternalStorageDirectory(), "myfolder"), "file.ext");
Uri uri = FileProvider.getUriForFile(context, fileProvider, file);

Your uri path would then yield the following

content://fileprovider/my_files/myfolder/file.ext

If you had supplied a path in your provider file then your uri path would look like this:

content://fileprovider/my_files/file.ext

Pztar
  • 4,274
  • 6
  • 33
  • 39
  • what is fileprovider ? in content://fileprovider/my_files/file.ext – Rajesh Koshti Mar 25 '17 at 11:47
  • 2
    The "path" element must be defined in your xml definitions under . To specify the root directory use: path="." – GregM May 15 '17 at 16:01
  • It's very important to use `Environment.getExternalStorageDirectory()` rather than hardcode path which starts with `file://`. – o0omycomputero0o Nov 12 '18 at 10:02
  • i am using Android P now the path i am getting is content://com.jack.videoeditor.provider/root/storage/emulated/0/Movies/VID-20190621-WA0006.mp4 but the mp4 is not playing on player pls Help me here i am using – Sunil Chaudhary Jul 10 '19 at 10:06
9
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_files"
        path="." />
    <external-files-path
        name="external_files"
        path="." />
    <!-- FOR SD CARD-->
    <root-path
        name="sdcard1"
        path="." />
</paths>
4

I fixed it

<!--THIS IS EVIL-->
    <root-path
        name="sdcard1"
        path="." />
Sujith S Manjavana
  • 1,417
  • 6
  • 33
  • 60
  • 1
    The Lint shows "Element root-path is not allowed here more...", but without this, the functionality won't work. Evil, really evil! – Pranav Karnik Jul 31 '19 at 04:30
2

File Provider
java.lang.IllegalArgumentException: Failed to find configured root that contains It is due to path is configured correctly in fileprovider_path.xml declared in manifest. whether it may be image path external-file path etc so declare as mentioned.

<?xml version="1.0" encoding="utf-8"?>
    <paths>
      <external-path
        name="external"
        path="." />
      <external-files-path
        name="external_files"
        path="." />
    <files-path
        name="files"
        path="." />
    </paths>
mani
  • 709
  • 6
  • 13
1

I had the same thing. In my case I had to clean the build in Android Studio (Build > Clean Project) every time I modified the path of the fileprovider in 'file_paths.xml'.

Martin Klomp
  • 442
  • 5
  • 5
0

In <external-path name="mypath" path="AppName" />

name="mypath" - mypath must be a specific piece from your image file name, say name="IMG" would work if all your image files have "IMG" in their name, judging by your sample code it is the case here.

path="AppName" is a folder name that you created in external for your images and it needs "/" at the end, i.e. path="AppName/"

so, <external-path name="IMG" path="AppName/" /> should do it and FileProvider should find and let other apps access your images when you request Uri with FileProvider.getUriForFile().

Hope it helps.

Boris Gafurov
  • 1,427
  • 16
  • 28
0

Replace your xml path with

<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
<external-files-path 
name="extfiles" path="."/> </paths>
Yakub
  • 71
  • 12
  • The path="." is what I found in my own research to stay at the top level. If you go through FileProvider more closely, you'll see that the path read from XML gets canonicalized. – Yakub Jun 24 '19 at 10:09