FileProvider沒法獲取外置SD卡問題解決方案 | Failed to find configured root that contains

隨着Android版本愈來愈高,Android官方對用戶數據保護力度也愈來愈大。Android提供FileProvider類來供應用之間共享數據。html

如:java

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="my_images" path="images/"/>
    ...
</paths>

FileProvider所支持的幾種path類型

從Android官方文檔上能夠看出FileProvider提供如下幾種path類型:android

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

該方式提供在應用的內部存儲區的文件/子目錄的文件。它對應Context.getFilesDir返回的路徑:eg:」/data/data/com.jph.simple/files」。git

<cache-path name="name" path="path" />

該方式提供在應用的內部存儲區的緩存子目錄的文件。它對應getCacheDir返回的路徑:eg:「/data/data/com.jph.simple/cache」;github

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

該方式提供在外部存儲區域根目錄下的文件。它對應Environment.getExternalStorageDirectory返回的路徑:eg:」/storage/emulated/0」;緩存

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

該方式提供在應用的外部存儲區根目錄的下的文件。它對應Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)返回的路徑。eg:」/storage/emulated/0/Android/data/com.jph.simple/files」。ide

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

該方式提供在應用的外部緩存區根目錄的文件。它對應Context.getExternalCacheDir()返回的路徑。eg:」/storage/emulated/0/Android/data/com.jph.simple/cache」。ui

以上即是Android官方文檔上介紹的FileProvider全部支持的因此path類型,這些類型在Android手機內部存儲區文件共享是能夠行的通的,但對於外置SD卡是不行的,若是你想經過FileProvider.getUriForFile()獲取一個外置SD卡的Uri則會報出以下異常:spa

Caused by- java.lang.IllegalArgumentException- Failed to find configured root that contains

FileProvider獲取對外置SD卡的支持

從Android官方文檔中沒有找到FileProvider對外置SD卡的支持的任何說明,下面咱們就從FileProvider的源碼中找找是否有突破口,在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支持的path類型中有個TAG_ROOT_PATH,它對應的值爲root-pathroot-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

從上圖能夠看出root-path表明/也就是Android設備的根目錄,該目錄下包含着手機內部存儲器,外置SD卡等全部文件的目錄。

而後咱們容許程序,發現將path設置爲root-path解決了FileProvider沒法使用外置SD卡的問題。

最後

既然來了,留下個喜歡再走吧,鼓勵我繼續創做(^_^)∠※

若是喜歡個人文章,那就關注個人博客devio.org吧,讓咱們一塊兒作朋友~~

戳這裏,加關注哦:

微博:第一時間獲取推送 
我的博客:乾貨文章都在這裏哦
GitHub:個人開源項目

相關文章
相關標籤/搜索