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:个人开源项目

相关文章
相关标签/搜索