美文网首页Android爱码蛋android高级
FileProvider无法获取外置SD卡问题解决方案 | Fa

FileProvider无法获取外置SD卡问题解决方案 | Fa

作者: CrazyCodeBoy | 来源:发表于2016-10-20 20:18 被阅读20157次

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

    该方式提供在应用的内部存储区的文件/子目录的文件。它对应Context.getFilesDir返回的路径:eg:"/data/data/com.jph.simple/files"。

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

    该方式提供在应用的内部存储区的缓存子目录的文件。它对应getCacheDir返回的路径:eg:“/data/data/com.jph.simple/cache”;

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

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

    该方式提供在应用的外部缓存区根目录的文件。它对应Context.getExternalCacheDir()返回的路径。eg:"/storage/emulated/0/Android/data/com.jph.simple/cache"。

    以上便是Android官方文档上介绍的FileProvider所有支持的所以path类型,这些类型在Android手机内部存储区文件共享是可以行的通的,但对于外置SD卡是不行的,如果你想通过FileProvider.getUriForFile()获取一个外置SD卡的Uri则会报出如下异常:

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

    FileProvider获取对外置SD卡的支持

    从Android官方文档中没有找到FileProvider对外置SD卡的支持的任何说明,下面我们就从FileProvider的源码中找找是否有突破口,在FileProvider的源码源码中发现下面一段代码:

     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-pathroot-path

    从上图可以看出root-path代表/也就是Android设备的根目录,该目录下包含着手机内部存储器,外置SD卡等所有文件的目录。

    然后我们允许程序,发现将path设置为root-path解决了FileProvider无法使用外置SD卡的问题。

    相关文章

      网友评论

      • oO百味Oo:为什么使用 getRealPathFromUri
        File file = new File(audio_path);
        uri = FileProvider.getUriForFile(context, "com.android.music.provider", file); file还是会报错
      • oO百味Oo:<paths>
        <external-path
        name="external_files"
        path="" />

        <external-path
        name="files_root"
        path="Android/data/com.android.music/download/"/>

        <root-patch
        name="root-patch"
        path="." />

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

        </paths> 这样写可以吗?
      • 亚欧沙龙:问题已解决,谢大佬
      • b00dbd194c64:太好了,解决了我的问题。
      • Kane_adac:Android8.0 设置了不会生效。
      • 早起的鸟儿写代码:我设置了后可以了,解决了问题 华为荣耀 安卓7.0。 但是还是想问下图片不放在项目包名根目录下,放到cache文件夹里面去?
      • 650e0ab4ae56:。。。我设置成root-path之后没有用,还是报这个错误
        xne110_929:@浅默Lynn 这个可以
        浅默Lynn:<external-path
        name="myImages"
        path="." />
        即可

      本文标题:FileProvider无法获取外置SD卡问题解决方案 | Fa

      本文链接:https://www.haomeiwen.com/subject/iufquttx.html