文档章节

FileProvider无法获取外置SD卡问题解决方案 | Failed to find configured root that contains

丁佳辉
 丁佳辉
发布于 07/15 15:00
字数 864
阅读 32
收藏 1

随着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 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-path

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

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

最后

既然来了,留下个喜欢再走吧,鼓励我继续创作(^_^)∠※

如果喜欢我的文章,那就关注我的博客devio.org吧,让我们一起做朋友~~

戳这里,加关注哦:

微博:第一时间获取推送 
个人博客:干货文章都在这里哦
GitHub:我的开源项目

本文转载自:http://www.devio.org/2016/10/20/FileProvider%E6%97%A0%E6%B3%95%E8%8E%B7%E5%8F%96%E5%A4%96%E7%BD%A...

丁佳辉
粉丝 20
博文 448
码字总数 205058
作品 0
浦东
程序员
私信 提问
我的三星手机内置SD卡开机无法自动加载

我一直用的一个三星手机,采用原厂的ROM就没有问题,一旦刷成比较新的4.2版本,就会出现(经常性的)内置SD卡无法自动加载的问题。这是一个很讨厌的问题,因为一旦内置的SD卡无法加载,很多应...

小穷博士
2013/10/26
1K
0
Android 外部存储权限分析

不知道你有么有发现,来自菜鸟的成长史:http://blog.csdn.net/zjbpku/article/details/25161131, KitKat之后的版本不再支持用户对外置SDcard(Secondary Storage)的写入等操作。如果用户想要...

sflfqx
2015/02/09
176
0
FileProvider共享文件

在应用间共享文件 对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故...

飛飛萨
2017/05/10
0
0
Android第四课 adb常用指令

1启动adb服务 adb start-server 2停止adb服务 adb kill-server 3显示所有的设备 adb devices C:UsersAdministrator>adb devices -l List of devices attached Y5NBLF9T85T4Y94D device produ......

fengyuzaitu
2018/08/07
0
0
Android手机自带内部存储路径的获取

我有一台中兴的Android手机,型号是 ZTE U930HD,手机没有插入外置SD卡(也就是Micro SD Card,原名Trans-flash Card(TF卡),2004年正式更名为Micro SD Card),但是机身自带了一个内置存储...

Cundong
2014/07/08
65.4K
4

没有更多内容

加载失败,请刷新页面

加载更多

ES6

ES6:不改变原理的基础上,让API变得更简单 一、let:代替var用于声明变量 1、var的缺点: (1)声明提前 (2)没有块级作用域 2、let的优点: (1)组织了申明提前 (2)让let所在的块({}),...

wytao1995
今天
3
0
kubernetes 环境搭建 —— minikube

创建集群 minikube start 搭建好 k8s 集群后,可以查看集群的状态以及部署应用。主要用到的是 k8s 的 api,这通常需借助于 kutectl 命令行工具 基本操作 kubectl versionkubectl cluster-i...

lemos
今天
9
0
关于js混淆与反混淆还原操作

使用js的混淆加密,其目的是为了保护我们的前端代码逻辑,对应一些搞技术吃饭的公司来说,为了防止被竞争对手抓取或使用自己的代码,就会考虑如何加密,或者混淆js来达到代码保护。 1、为什么...

开源oschina
今天
11
0
用盛金公式解三次方程(ansi c版)

/* cc cubic.c -lm gcc cubic.c -lm Shengjin's Formulas Univariate cubic equation aX ^ 3 + bX ^ 2 + cX + d = 0, (a, b, c, d < R, and a!= 0). Multiple root disc......

wangxuwei
今天
9
0
JBolt开发平台入门(16)- 弹出Dialog显示指定区域的html内容

在JBolt里,有个主从表Demo。 子表中除了普通的table显示,还有其它从表显示形式 比如下方案例:是针对一个升级管理子表中存放版本的changelog富文本信息。 需求是点击左上角的弹出查看按钮,...

山东-小木
今天
45
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部