In my Android Unity plugin, I want to provide access to the screenshot that unity made, so provide access to Application.persistentDataPath
, which is the files
folder of the app per documentation...
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="files" path="."/>
</paths>
I want also to read / write external storage. But as soon as I add...
<!-- For access `DICM/Camera` -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...to the manifest, Unity adds the screenshots to the external storage, so FileProvider
cannot provide files from there.
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/<PACKAGE_NAME>/files/<FILE_NAME>
How can I still provide files from app files
directory wherever it resides?
I usually see that message coming from getUriForFile()
, when you pass in a File
that does not match your configuration.
In your provider metadata, you are only supporting getFilesDir()
(and locations underneath it) as places that you are willing to serve from. However, the File
object that you passed into getUriForFile()
appears to be built from getExternalFilesDir()
, which is not the same thing.
Unfortunately, FileProvider
does not provide direct access to getExternalFilesDir()
. <external-path>
comes close, and the documentation claims that it points to getExternalFilesDir()
. That is a documentation bug; <external-path>
really points to the root of external storage (i.e., Environment.getExternalStorageDirectory()
).
Your options are:
Stick to FileProvider
just for your internal storage files, and use file://
Uri
values for the files on external storage
Work out an <external-path>
value to add to your provider metadata that points to your particular portion of external storage, based on your application ID
Use my StreamProvider
, which adds <external-files-path>
as an option
Roll your own ContentProvider
to handle this, rather than using either FileProvider
or StreamProvider