Reputation: 2651
I'm using FileProvider for my internal files to be exposed to the Gallery for example. To make it more uniform, I also put my my external files into the provider (via external-path) but for the files in removable sd card it doesn't work. Saying something like that folder is not authorized.
Any help will be greatly appreciated.
Upvotes: 10
Views: 7906
Reputation: 901
I added this root-path as suggested by @Gubatron in my XML and it works.
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
<root-path name="external_files" path="/storage/" />
</paths>
Upvotes: 28
Reputation: 326
To access external sdcard .
First call uri.getEncodedPath()
to get the encoded path
" /external_files/3161-3330/WhatsApp/Media/WhatsApp%20Documents/All%20Currency.pdf "
Then use below logic to get file path of external storage
public String getFilePath(){
if (isKitKat && DocumentsContract.isDocumentUri(mContext, uri)) {
// ExternalStorageProvider
if (com.android.externalstorage.documents.equals(uri.getAuthority())) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else {
return "/storage" + "/" + split[0] + "/" + split[1];
}
}
}
}
getFilePath()
will give :
/storage/emulated/0/3161-3330/WhatsApp/Media/WhatsApp Documents/All Currency.pdf
where uri path starts with
/external_files/
and file path starts with
/storage/
Hence , we have to add below line
<root-path name="external_files" path="/storage/" />
in
@xml/provider_paths.xml
Upvotes: 0
Reputation: 7257
FileProvider
does not support secondary external storage (like removable sd cards). This is even more an issue in Android 7 and above - because you can't use the file://
uris anymore.
I already issued a bug report here.
Upvotes: 2
Reputation: 856
Let's take a look at FileProvider
code:
private static PathStrategy parsePathStrategy(Context context, String authority)
...
int type;
while ((type = in.next()) != END_DOCUMENT) {
if (type == START_TAG) {
final String tag = in.getName();
final String name = in.getAttributeValue(null, ATTR_NAME);
String path = in.getAttributeValue(null, ATTR_PATH);
File target = null;
if (TAG_ROOT_PATH.equals(tag)) {
target = buildPath(DEVICE_ROOT, path);
} else if (TAG_FILES_PATH.equals(tag)) {
target = buildPath(context.getFilesDir(), path);
} else if (TAG_CACHE_PATH.equals(tag)) {
target = buildPath(context.getCacheDir(), path);
} else if (TAG_EXTERNAL.equals(tag)) {
target = buildPath(Environment.getExternalStorageDirectory(), path);
}
if (target != null) {
strat.addRoot(name, target);
}
}
}
return strat;
}
FileProvider
accepted absolute pathes to directory with help of tag root-path
(DEVICE_ROOT constant). So just add absolute path to your files folder in secondary external disc like below:
<root-path path="/storage/extSdCard/Android/data/com.edufii/files/image/" name="image-ext2" />
<root-path path="/storage/extSdCard/Android/data/com.edufii/files/video/" name="video-ext2" />
<root-path path="/storage/extSdCard/Android/data/com.edufii/files/datafile/" name="datafile-ext2" />
<root-path path="/storage/extSdCard/Android/data/com.edufii/files/audio/" name="audio-ext2" />
Note official documentation doesn't say anything about <root-path>
, so it may changed in a future.
Upvotes: 7
Reputation: 8211
starting from android 4.4, normal applications are not allowed to access secondary external storage devices, i.e. sd card, except in their package-specific directories, even if you have requested WRITE_EXTERNAL_STORAGE permission.
The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled.
https://source.android.com/devices/storage/
Upvotes: 1