Android 7.0 通过FileProvider共享文件
一.概述
Android 7.0后,提供了很多新特性,其中最主要的是禁止了通过file://URI直接在文件操作共享文件(该操作会触发FileUriExposedException),而是通过content://URI来实现共享。
FileRrovider是ContentProvider的子类,用于不同应用间的文件共享。
二 使用
1.在Mainfest文件中声明provider。
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
2.编写资源文件provider_paths。
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name = "root" path = ""/> <files-path
name="files"
path=""/> <cache-path
name="cache"
path=""/> <external-path
name="external"
path=""/> <external-files-path
name="external-file"
path=""/> <external-cache-path
name="external-cache"
path=""/>
</paths>
在paths节点内部支持以下几个子节点,分别为:
- <root-path/> 代表设备的根目录new File("/");
- <files-path/> 代表context.getFilesDir()
- <cache-path/> 代表context.getCacheDir()
- <external-path/> 代表Environment.getExternalStorageDirectory()
- <external-files-path>代表context.getExternalFilesDirs()
- <external-cache-path>代表getExternalCacheDirs()
path代表目录下的子目录,如:
<cache-path
name = "cache"
path = "path
/>
代表context.getChcheDir()/path目录,如果path为空,代表直接使用该根目录。
既然要使用content://URI替代file://URI,那么我们需要一个虚拟路径对真实文件路径进行映射。通过编写xml文件,其中path路径确定了可访问的文件目录,name属性映射了真实文件路径。
3.使用fileProvider API 安装APK
我们一般编写安装APK操作时,是这么写的。
private void installAPK() {
File file = new File(Environment.getExternalStorageDirectory(),"test.apk"); Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
startActivity(intent); }
拿着在7.0上的手机跑一下,果不其然会报android.os.FileUriExposedException。
简单修改下URI的获取方式。
private void installAPK() {
File file = new File(Environment.getExternalStorageDirectory(),"test.apk"); Intent intent = new Intent(Intent.ACTION_VIEW);
Uri fileUri = null;
if(Build.VERSION.SDK_INT >= 24){
//输出 content://com.example.fanggao.fgtextdemo/external/test.apk
fileUri = FileProvider.getUriForFile(this,BuildConfig.APPLICATION_ID+".fileProvider",file);
}else {
fileUri = Uri.fromFile(file);
}
intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivity(intent); }
这样就可以正常运行了。注意,我们还需要加上权限,否则会报Permission Denial异常。
那么问题来了,当我们直接使用fileProvider时,在5.0以下的手机也会报Permission Denial异常,是不是也可以使用addFlags()方法添加权限呢?
答案是不行的,但addFlags只是使用与setData,setDataandType以及setClipData,而且该方法在5.0以下是无效的,需要使用grantUrlPermission()方法,获取所有符合授权的应用,全部授权。
三 小结
7.0后使用fileProvider来实现文件共享,主要目的是隐藏真实的文件目录,因为fileProvider是ContentProvider的子类,所以需要在AndroidManifest.xml文件中注册;并且需要编写xml文件描述可使用的文件夹目录,通过name 去映射文件真实目录,实现访问的安全性。
另外获取授权的方式有2种,
1.通过addFlags()来获取,仅使用setData,setDataandType以及setClipData方法传递uri时支持。
2.通过grantUrlPermission()方式,具体参考下文博客。
更多参考博客:
https://blog.csdn.net/lmj623565791/article/details/72859156
Android 7.0 通过FileProvider共享文件的更多相关文章
- Android 7.0应用之间共享文件
原文首发于微信公众号:躬行之,欢迎关注交流! 开发中经常需要将某个文件向另一个应用程序传递,如图片上传到另一个应用程序.文件在不同存储路径之间的复制粘贴等都需要共享文件,可以这样理解接收文件的应用是在 ...
- Android 7.0 出现 ”FileUriExposedException“ 和 ”解析包出现错误“ 异常的解决办法
问题1 :android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.xxx.xxx.xxx.rel ...
- android 7.0+ FileProvider 访问隐私文件 相册、相机、安装应用的适配
从 Android 7.0 开始,Android SDK 中的 StrictMode 策略禁止开发人员在应用外部公开 file:// URI.具体表现为,当我们在应用中使用包含 file:// URI ...
- android 7.0以上共享文件(解决调用系统照相和图片剪切出现的FileUriExposedException崩溃问题)
在android7.0开始试共享“file://”URI 将会导致引发 FileUriExposedException. 如果应用需要与其他应用共享私有文件,则应该使用 FileProvider, F ...
- android 7.0 应用间文件共享FileProvider
1.官方教程 Android 7.0 以后安全系数提高,应用间文件共享要使用FileProvider.原来的 file:/// Uri 替换为 content://Uri https://devel ...
- Android 7.0 FileProvider 使用说明
FileProvider FileProvider 这个组件在Android 22.0.0 (也就是 Android 5.0 ) 版本下加入进Android系统,该组件是ContentProvider ...
- 关于Android 7.0(API24)相机的问题汇总
在开发Android项目的时候,我们会用到相机,有些时候只是开发一个普通的扫码,仅仅赋予一下 权限 就好了,但是有些时候是需要拍照和从相册中获取照片的.我们在Android 5.0以及5.0之前调用相 ...
- Android 7.0下,拍摄照片报错
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI.如果一项包含文件 URI 的 intent 离开 ...
- Android 7.0 行为变更
Android 7.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 如果您之前发布过 Android 应用,请注意 ...
随机推荐
- LVS详细介绍以及遇到的坑
LVS详细介绍以及遇到的坑 一,概述 本文介绍了我搭建LVS集群的步骤,并且在使用LVS(Linux Virtual Server)过程中遇到的问题和坑, 二,LVS简单介绍 大家都知道,LVS中文意 ...
- Java面试问题汇总
转一些面试经验 刚看到下面这份面试清单,从个人的开发面试经历看,里面总结的大部分内容还是很不错的.年后想跳槽的朋友可以选取里面的问题准备一下. GitHub上的面试总结帖 Interview-Note ...
- 批处理判断是BIOS还是UEFI启动
https://files.cnblogs.com/files/liuzhaoyzz/detectefi.rar @echo offpushd %~dp0reg add "HKEY_CURR ...
- c#委托之浅析
前言: 这章我们将弄懂,委托是什么?有什么作用?在什么样的场景下可以启到什么作用? 委托适用的场景:当确定处理一个任务时,不确定其处理任务的方法时可使用,这样可以提高扩展性,调用符合条件的处理方法,避 ...
- OPPO R6007在哪里打开usb调试模式的完美流程
当我们使用Pc接通安卓手机的时候,如果手机没有开启USB开发者调试模式,Pc则无法成功读到我们的手机,遇到此种情况我们需要想方设法将手机的USB开发者调试模式打开,以下内容我们讲解OPPO R6007 ...
- web安全类
web安全类主要分为两个部分:CSRF和XSS 一.CSRF 基本概念:CSRF,通常称为跨站请求伪造,英文名Cross-site request forgery 缩写为CSRF; 怎么防御 1.To ...
- C++primer第一章(部分)
1.4.2 for 语句 for (init-statement; condition; expression) statement; step1:初始化 step2:判断条件,为真则执行循体:为假则 ...
- windows短路径转换成长路径
参考: https://blog.csdn.net/wxqian25/article/details/43951281 https://docs.microsoft.com/en-us/windows ...
- Troubleshooting 10g and 11.1 Clusterware Reboots (文档 ID 265769.1)
Troubleshooting 10g and 11.1 Clusterware Reboots (文档 ID 265769.1) This document is intended for DBA' ...
- Linux SVN 操作详解(转)
1.将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn://192.168.1.1/pro/domain ...