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

隨著Android版本越來越高,Android官方對(duì)用戶數(shù)據(jù)保護(hù)力度也越來越大。Android提供FileProvider類來供應(yīng)用之間共享數(shù)據(jù)。

如:

<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" />

該方式提供在應(yīng)用的內(nèi)部存儲(chǔ)區(qū)的文件/子目錄的文件。它對(duì)應(yīng)Context.getFilesDir返回的路徑:eg:"/data/data/com.jph.simple/files"。

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

該方式提供在應(yīng)用的內(nèi)部存儲(chǔ)區(qū)的緩存子目錄的文件。它對(duì)應(yīng)getCacheDir返回的路徑:eg:“/data/data/com.jph.simple/cache”;

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

該方式提供在外部存儲(chǔ)區(qū)域根目錄下的文件。它對(duì)應(yīng)Environment.getExternalStorageDirectory返回的路徑:eg:"/storage/emulated/0";

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

該方式提供在應(yīng)用的外部存儲(chǔ)區(qū)根目錄的下的文件。它對(duì)應(yīng)Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)返回的路徑。eg:"/storage/emulated/0/Android/data/com.jph.simple/files"。

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

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

以上便是Android官方文檔上介紹的FileProvider所有支持的所以path類型,這些類型在Android手機(jī)內(nèi)部存儲(chǔ)區(qū)文件共享是可以行的通的,但對(duì)于外置SD卡是不行的,如果你想通過FileProvider.getUriForFile()獲取一個(gè)外置SD卡的Uri則會(huì)報(bào)出如下異常:

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

FileProvider獲取對(duì)外置SD卡的支持

從Android官方文檔中沒有找到FileProvider對(duì)外置SD卡的支持的任何說明,下面我們就從FileProvider的源碼中找找是否有突破口,在FileProvider的源碼源碼中發(fā)現(xiàn)下面一段代碼:

 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類型中有個(gè)TAG_ROOT_PATH,它對(duì)應(yīng)的值為root-path,root-path在Android官方文檔中是沒有提及的,但我們不妨試一下,將FileProvider的path設(shè)置成root-path,看能否支持外置SD卡:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <root-path path="" name="camera_photos" />
    </paths>
</resources>

然后我們能將在FileProvider類中設(shè)置斷點(diǎn),查看root-path
究竟代表什么:

root-path
root-path

從上圖可以看出root-path代表/也就是Android設(shè)備的根目錄,該目錄下包含著手機(jī)內(nèi)部存儲(chǔ)器,外置SD卡等所有文件的目錄。

然后我們?cè)试S程序,發(fā)現(xiàn)將path設(shè)置為root-path解決了FileProvider無法使用外置SD卡的問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容