400

I'm trying to take a picture with camera, but I'm getting the following error:

FATAL EXCEPTION: main
Process: com.example.marek.myapplication, PID: 6747
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.marek.myapplication/files/Pictures/JPEG_20170228_175633_470124220.jpg
    at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
    at com.example.marek.myapplication.MainActivity.dispatchTakePictureIntent(MainActivity.java:56)
    at com.example.marek.myapplication.MainActivity.access$100(MainActivity.java:22)
    at com.example.marek.myapplication.MainActivity$1.onClick(MainActivity.java:35)

AndroidManifest.xml:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.marek.myapplication.fileprovider"
        android:enabled="true"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

Java:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            Toast.makeText(getApplicationContext(), "Error while saving picture.", Toast.LENGTH_LONG).show();
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,
                    "com.example.marek.myapplication.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="images/"/>
</paths>

I was searching whole day about this error and trying to understand FileProvider, but I have no idea what this error message tries to tell me. If you want more info/code, write me in the comment.

capo11
  • 790
  • 3
  • 11
  • 32
Pivoman
  • 4,435
  • 5
  • 18
  • 30
  • 5
    Can you also paste createImageFile method code? – Ankit Batra Apr 28 '17 at 23:03
  • I'm so sorry, but **I canceled this project and I'm not working on it anymore**. I will accept the most favorite answer to "close" this question. Thanks to all for participation and I hope it helps to others. – Pivoman Sep 14 '17 at 12:26
  • Ran into the same issue. Found this solution to get a basic FileProvider setup going using a minimal github example project: https://stackoverflow.com/a/48103567/2162226 . It provides steps for which files to copy over (without making changes) into a local standalone project – Gene Bo Jan 04 '18 at 21:36
  • This issue is now fixed in Delphi 10.4: https://quality.embarcadero.com/browse/RSP-26950 – Dave Nottage May 27 '20 at 21:55

35 Answers35

587

Your file is stored under getExternalFilesDir(). That maps to <external-files-path>, not <files-path>. Also, your file path does not contain images/ in it, so the path attribute in your XML is invalid.

Replace res/xml/file_paths.xml with:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="my_images" path="/" />
</paths>

UPDATE 2020 MAR 13

Provider path for a specific path as followings:

  • <files-path/> --> Context.getFilesDir()
  • <cache-path/> --> Context.getCacheDir()
  • <external-path/> --> Environment.getExternalStorageDirectory()
  • <external-files-path/> --> Context.getExternalFilesDir(String)
  • <external-cache-path/> --> Context.getExternalCacheDir()
  • <external-media-path/> --> Context.getExternalMediaDirs()

Ref: https://developer.android.com/reference/androidx/core/content/FileProvider

Ban Markovic
  • 690
  • 1
  • 7
  • 12
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 6
    ok, I added external-files-path, but i have still the same error :/ There is maybe more bugs. I'm using emulator android device, do I have to create that folder or something? – Pivoman Feb 28 '17 at 19:09
  • @Pivoman: If you are getting the exact same error ("Failed to find configured root" with the same general path)... the only explanation that I can think of is that you are using an old version of the Android Support libraries. Make sure that you are using a current version (e.g., `25.2.0`). Otherwise, I do not know what to tell you. – CommonsWare Feb 28 '17 at 19:13
  • I have newest versions of all libraries. – Pivoman Feb 28 '17 at 19:23
  • 25
    "'path' attribute should be defined" we are missing here path in the configuration. – blackjack Dec 07 '17 at 09:15
  • 2
    I was having a problem with multiple paths on Android 5. Left only one path, instead of 2. – ODAXY Feb 01 '18 at 12:20
  • 9
    I received one crash report (out of 50-100 devices, I think) that is identical to this. ` ` 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. My best guess is that `ContextCompat#getExternalFilesDirs` returned null @line 616 (v26.0.1), so a PathStrategy wasn't registered. This occurred on Huawei device. – androidguy Mar 13 '18 at 01:20
  • 23
    Instead of using – Safeer Jun 28 '18 at 14:08
  • @androidguy did you find a solution? – tanay tandon Mar 07 '19 at 10:51
  • @tanaytandon Not in a satisfactory sense. I put `FileProvider.getUriForFile` in try, catch IllegalArgumentException and treat it as if the device storage is unavailable. It's quite possible that it will consistently fail on the affected device. – androidguy Mar 18 '19 at 21:45
  • I find it completely bizarre that you complain that `path` is set to `images/` which is not in the file path, and then proceed to set `path` to something else which is not in the file path?? – Nimitz14 Jun 27 '19 at 14:55
  • 1
    @Nimitz14: That was [somebody else's edit to my answer](https://stackoverflow.com/posts/42516202/revisions). I will revert that momentarily. – CommonsWare Jun 27 '19 at 14:58
  • @CommonsWare why did you revert fix with "path=..." ? It seems to be mandatory. – Dmitriy Pavlukhin Nov 04 '19 at 21:54
  • @DmitriyPavlukhin: First, it is not mandatory. If you are seeing a complaint in Android Studio, that is an over-zealous Lint check. Second, even if you want `path`, the right answer would be `path="/"` in this case, not `path="my_images"` as the edit had. – CommonsWare Nov 04 '19 at 22:28
  • @CommonsWare it would be amazing if you'd add this comment to your answer, look at the most popular comment here) – Dmitriy Pavlukhin Nov 05 '19 at 19:57
  • worked for me. only worked on my emulator – Doilio Matsinhe Mar 06 '20 at 11:44
  • This worked for me – LMK IND Apr 25 '20 at 14:53
  • 1
    I have got this, but it is a bit strange it should be storage/0/Android.../ but ```Fatal Exception: java.lang.IllegalArgumentException Failed to find configured root that contains /storage/3915-9DD5/Android/data/com.my.packagename/cache/8d914ae4-c1a1-4c64-b2ab-ee454b43bc0c/Status Quo - In The Army Now.mp3``` – nAkhmedov Oct 14 '21 at 09:47
  • @nAkhmedov: `FileProvider` does not support removable storage, and that filesystem path looks like it is from removable storage. – CommonsWare Oct 14 '21 at 10:49
  • @CommonsWare thank you for reply? what a approach do you suggest for me? My FileProvider works with external-cache dir folder. – nAkhmedov Oct 14 '21 at 13:17
  • @nAkhmedov: Either do not work with removable storage, or write your own `ContentProvider` to serve the files from removable storage. – CommonsWare Oct 14 '21 at 13:21
  • FYI: I have the correct configuration (as per this answer) but still receive crash report form some Huawei devices (see @androidguy comment) More info about Huawei devices and this problem here: https://stackoverflow.com/questions/39895579/fileprovider-geturiforfile-error-on-huawei-devices – Pascal Mar 20 '23 at 07:39
  • Fortunately I don't need to pay special attention to Huawei as my app is not popular in Asia, in fact only published in a few countries there and hardly any users. – androidguy Mar 21 '23 at 22:55
343

This may resolve everyones problem: All tags are added so you don't need to worry about folders path. Replace res/xml/file_paths.xml with:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-path
    name="external"
    path="." />
  <external-files-path
    name="external_files"
    path="." />
  <cache-path
    name="cache"
    path="." />
  <external-cache-path
    name="external_cache"
    path="." />
<files-path
    name="files"
    path="." />
</paths>

EDIT: 1st June 2021

We should use only specific path which we need. Try alternate path on your own and use which you needed.

See Accepted answer for more information: https://stackoverflow.com/a/42516202/4498813

Mitul Varmora
  • 3,832
  • 1
  • 12
  • 21
  • Yes, you right bro. This is most common working solution for all related problems. – Mitul Varmora Mar 26 '19 at 05:28
  • But why are you giving access of every folder? – Bugs Happen Jul 03 '19 at 12:12
  • If someone stuck and can not find solution then this generic solution may work for them at list. and also you don't need to worry about folders path if you are accessing more from storage. @BugsHappen – Mitul Varmora Jul 04 '19 at 16:18
  • 1
    Simple solution ... but for this brilliant! I used a provider then I entered the user possibility to change the destination directory ... nothing worked anymore because at that point the provider should be dynamic .... you saved my day! – Bronz Sep 06 '19 at 16:15
  • 2
    used this solution and the code started working. Removed unnecessary code by testing which one of these was working – Kartik Nov 08 '19 at 06:30
  • Already upvoted. @Mitul I need your one more help. What is the permission should I give if I am trying to access file in the root path of apk for below Android 24 ? I get error Unable to open '/data/user/0/com.ibm.appcenter/files/sample.com.android.apk': Permission denied . Basically I am trying to install apk downloaded in a path /data/user/0/com.ibm.appcenter/files/ Above Android 24 it works as I am using file provider. – manjunath kallannavar Dec 12 '19 at 09:47
  • @manjunathkallannavar Just download your file in context.cacheDir folder and access over their. – Mitul Varmora Dec 16 '19 at 08:56
  • 1
    Great worked for me, as a new learner it made me realise I wasn't getting from external files but cache – Tony Merritt Feb 23 '20 at 14:43
  • I still get the exception on some devices, even with these settings.. – John Doe Sep 22 '20 at 23:17
  • @JohnDoe Please give more details like - exception/error, your codes & Mobile model details. If you wants to fix it. – Mitul Varmora Sep 23 '20 at 08:44
  • @Kartik what tests did you performed to find which one is working? – ansh sachdeva Nov 17 '20 at 09:06
  • Also , for everyone, @commonsware mentions in their latest update (in the selected answer) that each of these tags to different functions. so what is the java part of this answer ? – ansh sachdeva Nov 17 '20 at 09:06
  • PLEASE don't do this. Follow the accepted answer and do not add a blanket allow-all rule in your app. File access security is part of the framework for a reason – Ed Holloway-George Oct 12 '22 at 21:01
95

Got similar problem after enabled flavors (dev, stage).

Before flavors my path resource looked like this:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
    name="my_images"
    path="Android/data/pl.myapp/files/Pictures" />
</paths>

After added android:authorities="${applicationId}.fileprovider" in Manifest appId was pl.myapp.dev or pl.myapp.stage depends on flavor and app started crashing. I removed full path and replaced it with dot and everything started working.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="." />
</paths>
antygravity
  • 1,307
  • 10
  • 12
  • 7
    Worked for me. Thanks! How you came up with '.' notation ? – NightFury Dec 30 '17 at 21:00
  • 2
    @antygravity can you please provide reference/documentation of this solution ? – geekoraul Mar 06 '18 at 18:03
  • 9
    Are there any negative consequences of this solution? – RediOne1 Jul 27 '18 at 11:53
  • Worked for me , Thanks a lot. – Hiren Oct 07 '18 at 09:22
  • This should be the accepted answer! The only solution that worked – jujka Jun 05 '19 at 16:18
  • @geekoraul Based on my understanding the reason the "." annotation works is because that the external-file path is already specified by the "" tag. The dot annotation can also be written here as "./" which means current directory specified by "" (root of "external-path") ref -> https://developer.android.com/reference/androidx/core/content/FileProvider#SpecifyFiles – Haomin Jul 06 '21 at 14:28
60

I am sure I am late to the party but below worked for me.

<paths>
    <root-path name="root" path="." />
</paths>
rogersw8n
  • 709
  • 5
  • 4
49

If you are using internal cache then use.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="/" />
</paths>
Innocent
  • 703
  • 10
  • 21
  • 3
    thanks,my situation : I want installed an app which saved in /data/data/pkg_name/files,so my correct configure as follow: – aolphn May 10 '18 at 01:47
41

Lost 2 weeks trying to find some solution... If you arrive here after try everthing above:

1 - Verify if your tag provider are inside tag application

<application>

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

</application>

2 - If you try a lot paths way without success, then test with this:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <cache-path name="cache" path="." />
  <external-path name="external" path="." />

  <root-path name="root" path="." />
  <files-path name="my_images" path="/" />
  <files-path name="my_images" path="myfile/"/>
  <files-path name="files" path="." />

  <external-path name="external_files" path="." />
  <external-path name="images" path="Pictures" />
  <external-path name="my_images" path="." />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures" />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures/" />

  <external-files-path name="images" path="Pictures"/>
  <external-files-path name="camera_image" path="Pictures/"/>
  <external-files-path name="external_files" path="." />
  <external-files-path name="my_images" path="my_images" />

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

</paths>

Test this, if camera works, then start eliminate some lines and continue testing...

3 - No forget verify if camera are actived in your emulator.

Diego Venâncio
  • 5,698
  • 2
  • 49
  • 68
23

Be aware that external-path is not pointing to your secondary storage, aka "removable storage" (despite the name "external"). If you're getting "Failed to find configured root" you may add this line to your XML file.

<root-path name="root" path="." />

See more details here FileProvider and secondary external storage

Peter Shashkin
  • 239
  • 2
  • 2
20

This confusing me a bit too.

The problem is on "path" attribute in your xml file.

From this document FileProvider 'path' is a subdirectory, but in another document (camera/photobasics) shown 'path' is full path.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>

I just change this 'path' to full path and it just work.

Supakij
  • 301
  • 2
  • 5
19

I would be late but I found a solution for it.Working fine for me, I just changed the paths XML file to:

 <?xml version="1.0" encoding="utf-8"?>
<paths>
    <root-path name="root" path="." />
</paths>
subbu
  • 215
  • 2
  • 4
15

Check how many storages your device offers - sharing files from secondary storage is not supported. Look at FileProvider.java source (from support-core-utils 25.3.1):

            } else if (TAG_EXTERNAL_FILES.equals(tag)) {
                File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null);
                if (externalFilesDirs.length > 0) {
                    target = externalFilesDirs[0];
                }
            } else if (TAG_EXTERNAL_CACHE.equals(tag)) {
                File[] externalCacheDirs = ContextCompat.getExternalCacheDirs(context);
                if (externalCacheDirs.length > 0) {
                    target = externalCacheDirs[0];
                }
            }

So, they take only the first storage.

Also, you can see that getExternalCacheDirs() is used to obtain list of storages through the ContextCompat interface. See documentation for its limits (it's told to not recognize USB Flashes for example). Best is to make some debug output of list of storages from this API on your own, so that you can check that path to storage matches the path passed to getUriForFile().

There's already a ticket assigned (as for 06-2017) in Google's issue tracker, asking to support more than one storage. Eventually, I found SO question on this as well.

lef
  • 1,196
  • 1
  • 9
  • 18
  • 2
    This in-depth answer should be getting more upvotes. Thank you for searching out what external storage FileProvider actually recognizes. – LarsH Oct 31 '17 at 14:47
15

I have spent 5 hours for this..

I have tried all the methods above but it depends on the what storeage your app currently using.

https://developer.android.com/reference/android/support/v4/content/FileProvider#GetUri

Check the documentation before trying the codes.

In my case since files-path sub directory will be Context.getFilesDir(). The funky thing is it Context.getFilesDir() notes one another subdirectory.

what I am looking for is

data/user/0/com.psh.mTest/app_imageDir/20181202101432629.png

Context.getFilesDir()

returns /data/user/0/com.psh.mTest/files

so the tag should be

....files-path name="app_imageDir" path="../app_imageDir/" ......

Then it works!!

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Seho Park
  • 159
  • 1
  • 3
  • 1
    Thanks for referring to documentation. It led me to the correct answer. In my case my file was saved with `getExternalStorageDirectory()` and I was supposed to provide the path with `` tag instead of `` – alierdogan7 Aug 14 '19 at 03:53
  • Thank you for this specific answer on files-path. It helped a lot. :) – arungiri_10 Jan 17 '20 at 04:10
  • Yes it works!!! the key point is to specify the ".." at the beginning of the path, like this path ="../myDirectory/" – Robert Apikyan Jun 04 '20 at 19:05
  • Thank you very much, it worked perfectly! The official documentation doesn’t say at any time that you need to put ".." for folders starting with "/app_myfolder/" – Antonio Oliveira Dec 31 '20 at 15:59
9

None of this worked for me. The only approach that works is not to declare an explicit path in xml. So do this and be happy:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="." />
</paths>

Here too has a excelent tutorial about this question: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s

8

My issue was that I had overlapping names in the file paths for different types, like this:

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

After I changed the names ("cached_files") to be unique, I got rid of the error. My guess is that those paths are stored in some HashMap or something which does not allow duplicates.

Jeopardy
  • 179
  • 1
  • 4
8

Change your main/res/xml/provider_paths.xml

From

<paths>
    <files-path path="images/" name="myimages" />
    <external-path name="download" path="download/"/>
</paths>

To

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external"
        path="." />
    <external-files-path
        name="external_files"
        path="." />
    <cache-path
        name="cache"
        path="." />
    <external-cache-path
        name="external_cache"
        path="." />
    <files-path
        name="files"
        path="." />
</paths>
Anand
  • 4,355
  • 2
  • 35
  • 45
4

This Worked for me as well.Instead of giving full path i gave path="Pictures" and it worked fine.

<?xml version="1.0" encoding="utf-8"?>
 <paths>
  <external-files-path
    name="images"
    path="Pictures">
  </external-files-path>
 </paths>
Amit Arora
  • 66
  • 3
3

What I did to solve this -

AndroidManifest.xml

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

filepaths.xml (Allowing the FileProvider to share all the files that are inside the app's external files directory)

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="files"
        path="/" />
</paths>

and in java class -

Uri fileProvider = FileProvider.getUriForFile(getContext(),"com.mydomain.fileprovider",newFile);
Rupam Das
  • 373
  • 9
  • 19
3

It depends what kind of storage you want to do, INTERNAL or EXTERNAL

for EXTERNAL STORAGE

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="my_images" path="my_images" />
</paths>

but for INTERNAL STORAGE, be careful with the path, because it uses getFilesDir() method which mean that your file will be located in the root directory for the app ("/")

  File storeDir = getFilesDir(); // path "/"

So your provider file must be like this:

<paths>
    <files-path name="my_images" path="/" />
</paths>
  • All examples assume that user is using external storage. I needed help with internal storage and it took hours to find this answer. Thank you. – zeeshan Apr 30 '19 at 05:52
2

I had the same problem, I tried the below code for its working.

1.Create Xmlfile : provider_paths

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="myfile/"/>
</paths>

2. Mainfest file

 <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.ril.learnet.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
 </provider>

3.In your Java file.

      File file =  new File(getActivity().getFilesDir(), "myfile");
        if (!file.exists()) {
            file.mkdirs();
        }
        String  destPath = file.getPath() + File.separator + attachmentsListBean.getFileName();

               file mfile = new File(destPath);
                Uri path;
                Intent intent = new Intent(Intent.ACTION_VIEW);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                {
                    path = FileProvider.getUriForFile(AppController.getInstance().getApplicationContext(), AppController.getInstance().getApplicationContext().getPackageName() + ".provider", mfile );
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                } else {
                    path = Uri.fromFile(mfile);
                }
   intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setDataAndType(path, "image/*");
                    getActivity().startActivity(intent);
Suresh kumar
  • 789
  • 10
  • 13
2

none of the above worked for me, after a few hours debugging I found out that the problem is in createImageFile(), specifically absolute path vs relative path

I assume that you guys are using the official Android guide for taking photo. https://developer.android.com/training/camera/photobasics

    private static File createImageFile(Context context) throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

Take note of the storageDir, this is the location where the file will be created. So in order to get the absolute path of this file, I simply use image.getAbsolutePath(), this path will be used in onActivityResult if you need the Bitmap image after taking photo

below is the file_path.xml, simply use . so that it uses the absolute path

<paths>
    <external-path
        name="my_images"
        path="." />
</paths>

and if you need the bitmap after taking photo

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Bitmap bmp = null;
        try {
            bmp = BitmapFactory.decodeFile(mCurrentPhotoPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
grandia
  • 709
  • 7
  • 20
2

If nothing helps and you are getting the error

failed to find configured root that contains /data/data/...

then try changing some line like:

File directory = thisActivity.getDir("images", Context.MODE_PRIVATE);

to:

File directory = new File(thisActivity.getFilesDir(), "images");

and in the xml file:

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

which is weird, since the folder I access is /images.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
2

The problem might not just be the path xml.

Following is my fix:

Looking into the root course in android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile():

    public File getFileForUri(Uri uri) {
        String path = uri.getEncodedPath();

        final int splitIndex = path.indexOf('/', 1);
        final String tag = Uri.decode(path.substring(1, splitIndex));
        path = Uri.decode(path.substring(splitIndex + 1));

        final File root = mRoots.get(tag); // mRoots is parsed from path xml
        if (root == null) {
            throw new IllegalArgumentException("Unable to find configured root for " + uri);
        }

        // ...
    }

This means mRoots should contains the tag of requested uri. So I write some code to print mRoots and tag of uri, and then easily find the tags do not match.

It comes out that setting provider authority as ${applicationID}.provider is a stupid idea! This authority is so common that might be used by other providers, which will mess up the path config!

thundertrick
  • 1,634
  • 1
  • 17
  • 22
2

I was getting this error Failed to find configured root that contains...

The following work around resolves my issue

res/xml/file_paths.xml

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

AndroidManifest.xml

<provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="[PACKAGE_NAME]"
      android:exported="false"
      android:grantUriPermissions="true">
         <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">
         </meta-data>
</provider>

ActivityClass.java

void shareImage() {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,"com.slappstudio.pencilsketchphotomaker", selectedFilePath));
        startActivity(Intent.createChooser(intent,getString(R.string.string_share_with)));
    }
Ali Tamoor
  • 896
  • 12
  • 18
1

Android official document says file_paths.xml should have:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures" />
</paths>

But to make it work in the latest android there should be a "/" at the end of the path, like this:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures/" />
</paths>
Shripad Bhat
  • 2,373
  • 2
  • 19
  • 21
1

The following change in xml file_paths file worked for me.

 <external-files-path name="my_images" path="Pictures"/>
 <external-files-path name="my_movies" path="Movies"/>
Manmohan Soni
  • 6,472
  • 2
  • 23
  • 29
1

My Problem Was Wrong File Name: I Create file_paths.xml under res/xml while resource was set to provider_paths.xml in Manifest:

<provider
        android:authorities="ir.aghigh.radio.fileprovider"
        android:name="android.support.v4.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

I changed provider_paths to file_paths and problem Solved.

Saeed Arianmanesh
  • 1,269
  • 2
  • 22
  • 33
1

If your file path is like /storage/emulated/0/"yourfile"

you just need modify your FileProvider xml

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

then call this function when you need share file

Intent sharingIntent = new Intent(Intent.ACTION_SEND);
                    Uri fileUri = FileProvider.getUriForFile(getContext(),
                            "com.example.myapp.fileprovider",
                            file);
                    sharingIntent.setType("*/*"); // any flie type
                    sharingIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
                    startActivity(Intent.createChooser(sharingIntent, "Share file"));

it works on android M ~ Pie

lazy
  • 149
  • 8
  • It's works! But can you explain why we use path="." instead of path="DCIM", "Pictures"...? – Hoang Lam May 08 '20 at 16:58
  • @Hoang Lam The difference is whether you need to specify a directory, in my example you can access all – lazy May 11 '20 at 00:13
1

The Answer from @CommonsWare is great.

But in my case, I had to add multiple paths.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="." />
    <files-path name="external_files" path="." />
</paths>
Thiago
  • 12,778
  • 14
  • 93
  • 110
0

I see that at least you're not providing the same path as others in file_paths.xml. So please make sure you provide the exact the same package name or path in 3 places including:

  • android:authorities attribute in manifest
  • path attribute in file_paths.xml
  • authority argument when calling FileProvider.getUriForFile().
Pei
  • 11,452
  • 5
  • 41
  • 45
0
  • For Xamarin.Android users

This could also be the result of not updating your support packages when targeting Android 7.1, 8.0+. Update them to v25.4.0.2+ and this particular error might go away(giving you´ve configured your file_path file correctly as others stated).


Giving context: I switched to targeting Oreo from Nougat in a Xamarin.Forms app and taking a picture with the Xam.Plugin.Media started failing with the above error message, so updating the packages did the trick for me ok.

Ahmed Alejo
  • 2,334
  • 2
  • 16
  • 16
0

I noticed that the policy or behaviour regarding the path.xml file changed between Support Library 26 and 27. For capturing a picture from the camera, I saw the following changes:

  • With 26, I had to use <external-path> and the full path given in the path argument.

  • With 27, I had to use <external-files-path> and only the subfolder in the path argument.

So what specifically worked for me with Support Library 27 as the path.xml file was

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="camera_image" path="Pictures/"/>
</paths>
Johan Paul
  • 2,203
  • 2
  • 22
  • 38
0

Hello Friends Try This

In this Code

1) How to Declare 2 File Provider in Manifest.

2) First Provider for file Download

3) second Provider used for camera and gallary

STEP 1

     <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

Provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="apks" path="." />
</paths>

Second Provider

     <provider
        android:name=".Utils.MyFileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true"
        tools:replace="android:authorities"
        tools:ignore="InnerclassSeparator">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path" />
    </provider>

file_path.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="storage/emulated/0" path="."/>
</paths>

.Utils.MyFileProvider

Create Class MyFileProvider (only Create class no any method declare)

When you used File Provider used (.fileprovider) this name and you used for image (.provider) used this.

IF any one Problem to understand this code You can Contact on rp1741995@gmail.com i will help you.

Rahul Patil
  • 129
  • 1
  • 5
0

In 2023, I met this problem. If you have already set the provider in your manifest and you still have this error——just add <root-path name="root" path="." /> in your xmls file." I need to do some thing to the file in USB device and add this line work for me. I hope it can help you!

JeckOnly
  • 347
  • 2
  • 10
-2

try this

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="my_images"
        path="" />
</paths>
  • 2
    Welcome to StackOverflow! You can improve the quality of your answer by adding an explanation ('Try this code, because...'). This will help others understand _why_ they should use your code. – Nander Speerstra Sep 14 '17 at 12:04
  • path cannot be empty – Michael Peterson Oct 03 '17 at 14:58
  • I think we should not down vote him, he is new on SO! All these downvotes block him from using SO! We can comment him and let him know how to help! Atleast he tried to help someone, he did not wrote all the informations because he was so new in the platform! – N Subedi Aug 03 '18 at 22:21
-2

You need to change the xml file file_paths.xml from

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="images/"/>
</paths>

to

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <exeternal-path name="my_images" path="Android/data/com.example.marek.myapplication/files/Pictures"/>
</paths>
Andrey
  • 7
  • 1
  • 1
    Although you have copied your answer from above, it is not properly done. Please correct the typing mismatch in your answer. – Abhinav Saxena Mar 25 '19 at 05:24
  • @AbhinavSaxena Please add a link to the comment that has a copy of this comment. Please compare the date. I don't found any comments with my recommendation (set 'path' attribute to correct string) on Mar 6 2019 at 14:36 and added the answer. If the answer has already been copied, I will remove the comment. – Andrey Jan 10 '22 at 15:21
-2

You need to ensure that the contents of your file_paths.xml file contains this string => "/Android/data/com.example.marek.myapplication/files/Pictures/"

From the error message, that is path where your pictures are stored. See sample of expected

files_path.xml below:

<external-path name="qit_images" path="Android/data/com.example.marek.myapplication/files/Pictures/" />

Oladipo Olasemo
  • 2,010
  • 24
  • 31