隨著Android版本越來越高,Android官方對用戶數據保護力度也越來越大。Android提供FileProvider類來供應用之間共享數據。
如:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_images" path="images/"/>
...
</paths>
FileProvider所支持的幾種path類型
從Android官方文檔上可以看出FileProvider提供以下幾種path類型:
<files-path path="" name="camera_photos" />
該方式提供在應用的內部存儲區(qū)的文件/子目錄的文件。它對應Context.getFilesDir返回的路徑:eg:"/data/data/com.jph.simple/files"。
<cache-path name="name" path="path" />
該方式提供在應用的內部存儲區(qū)的緩存子目錄的文件。它對應getCacheDir返回的路徑:eg:“/data/data/com.jph.simple/cache”;
<external-path name="name" path="path" />
該方式提供在外部存儲區(qū)域根目錄下的文件。它對應Environment.getExternalStorageDirectory返回的路徑:eg:"/storage/emulated/0";
<external-files-path name="name" path="path" />
該方式提供在應用的外部存儲區(qū)根目錄的下的文件。它對應Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)返回的路徑。eg:"/storage/emulated/0/Android/data/com.jph.simple/files"。
<external-cache-path name="name" path="path" />
該方式提供在應用的外部緩存區(qū)根目錄的文件。它對應Context.getExternalCacheDir()返回的路徑。eg:"/storage/emulated/0/Android/data/com.jph.simple/cache"。
以上便是Android官方文檔上介紹的FileProvider所有支持的所以path類型,這些類型在Android手機內部存儲區(qū)文件共享是可以行的通的,但對于外置SD卡是不行的,如果你想通過FileProvider.getUriForFile()
獲取一個外置SD卡的Uri則會報出如下異常:

FileProvider獲取對外置SD卡的支持
從Android官方文檔中沒有找到FileProvider對外置SD卡的支持的任何說明,下面我們就從FileProvider的源碼中找找是否有突破口,在FileProvider的源碼源碼中發(fā)現下面一段代碼:
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支持的path類型中有個TAG_ROOT_PATH
,它對應的值為root-path
,root-path
在Android官方文檔中是沒有提及的,但我們不妨試一下,將FileProvider的path設置成root-path
,看能否支持外置SD卡:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<root-path path="" name="camera_photos" />
</paths>
</resources>
然后我們能將在FileProvider類中設置斷點,查看root-path
究竟代表什么:

從上圖可以看出root-path
代表/
也就是Android設備的根目錄,該目錄下包含著手機內部存儲器,外置SD卡等所有文件的目錄。
然后我們允許程序,發(fā)現將path設置為root-path
解決了FileProvider無法使用外置SD卡的問題。