Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileProvider and secondary external storage

How can I serve files from the SECONDARY external storage using the FileProvider?

The current implementation of the FileProvider handles only the first directory returned by ContextCompat.getExternalFilesDirs

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

It seems, that there is no way to define a <path> entry for the FileProvider, that matches the secondary external storage path...

like image 322
artkoenig Avatar asked Oct 29 '16 10:10

artkoenig


2 Answers

And the answer is... FileProvider does not support that. With Android 7 this is even more an issue, due to deprecation of the file:// Uri scheme.

I issued a bug report.

like image 163
artkoenig Avatar answered Oct 03 '22 06:10

artkoenig


FileProvider not support secondary storage because of the code below:

Code from support:support-core-utils:26.1.0 FileProvider

            } else if (TAG_EXTERNAL_FILES.equals(tag)) {
                File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null);
                if (externalFilesDirs.length > 0) {
                    target = externalFilesDirs[0];// Code here, That's why!!!
                }
            } else if (TAG_EXTERNAL_CACHE.equals(tag)) {

However, there is a special TAG in FileProvider : root-path which is not covered in official reference.

            if (TAG_ROOT_PATH.equals(tag)) {
                target = DEVICE_ROOT;// DEVICE_ROOT = new File("/");
            } else if (TAG_FILES_PATH.equals(tag)) {

So, root-path matches all the path.

Just type this code in your FileProvider xml, then FileProvider can handle File in secondary storage.

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

Be aware, it may leak your directory structure.

like image 27
Shaw Avatar answered Oct 03 '22 05:10

Shaw