Android(安卓)7.0后访问文件权限:android.os.FileUriExposedException 的异常
最近项目中有一个很简单的需求:就是用系统自带图库打开在APP中下载的图片,结果就遇到了
android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/xxx.jpg exposed beyond app through Intent.getData()
的异常。
原来从Android 7.0开始,谷歌收回了访问文件的权限,即一个应用提供自身资源文件给其它应用使用时,如果给出 file://xxx 这样格式的URI的话,谷歌会认为目标应用不具备访问此文件的权限,便会抛出 FileUriExposedException 的异常。我这里的解决方法是使用 FileProvider,来生成一个content://xxx 格式的URI,并授予此 URI 临时访问权限,ok,异常解决了。下面我们来一起看看实现方式吧:
1.在 Manifest中声明FileProvider
name为 FileProvider的完整类名:android.support.v4.content.FileProvider ,是固定的;
authorities为自定义的权限名称,大家可以自定义,通常都会带上包名来避免与其他应用冲突;
exported为 false,代表只有同一个应用程序的组件或带有相同用户ID的应用程序才能使用,在 FileProvider的使用中一定要填false,否则会报错;
grantUriPermissions为true,代表允许通过接受传递的权限方式进行访问,拥有共享文件的临时权限。即如果应用A具有读取 ContentProvider 的权限,它去调用另一个应用B的activity,但是B没有读取此 ContentProvider 的权限,那么应用A可以将自己的权限通过intent传递给应用B,让其也具有访问此ContentProvider 的权限。(因此后面代码中会对Intent 进行设置: intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
2.在res下的xml文件夹中新建一个provider_paths.xml文件(名字可自定义,和上一步中resource的value一致即可)
内部的element可以是 files-path,cache-path,external-path等,代表的根目录分别对应为:Context.getFilesDir(),Context.getCacheDir(),Environment.getExternalStorageDirectory()等。
name是一个标识,作为根目录的名称,可以自定义;
path代表根目录下要共享的目标。
这里大家也许看的会有些困惑,我举个简单的例子:
大家都知道 ContentProvider 使用 URI 标识要操作的数据,这里的内容 URI 主要包括两部分:authority:整个提供程序的符号名称;path:指向表的名称/路径,所以内容 URI 统一的形式就是:content://authority/path。
那么当我们以上面为例,通过 FileProvider 获取到的某资源文件(比如根目录下的xxx.jpg)的uri链接即为:content://com.xxx.fileprovider/gallery_photos/xxx.jpg
3.在代码中调用(我这里就以实现用系统自带图库打开下载的一张图片为例了)
Intent intent = new Intent(Intent.ACTION_VIEW); Uri photoURI = FileProvider.getUriForFile(getApplicationContext(), "com.xxx.fileprovider", file);//file即为所要共享的文件的file intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//授予临时权限别忘了 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(photoURI, "image/*"); startActivity(intent);
ok,至此 FileProvider 的基本使用就完成了。
更多相关文章
- Android(安卓)apk文件拆解与重新打包
- android studio中xml文件报错: URI is not registered的解决办法
- Android::开机自启动C程序
- Android(安卓)TV 键值修改流程
- android 缓存 清理
- Android软件测试的日志文件问题
- Android如何在app中通过一个按钮直接跳转到的系统的权限设置页面
- Android(安卓)Studio中读取文本文件内容方法
- android flash分区(nand flash)