FileProvider

FileProvider 这个组件在Android 22.0.0 (也就是 Android 5.0 ) 版本下加入进Android系统,该组件是ContentProvider的子类,功能就是用来提供文件在跨进程间的访问能力。大家千万不要觉得是Android 7.0 才加入进来的。

为什么Android 7.0 文件共享要使用FileProvider

这个原因是因为,Android 7.0 版本以后,对于StrictMode的审查又严格了一步,就如在Android 3.0以后加入的NetWorkOnMainThread的异常一样,Google对于会对Android系统造成体验或者安全问题的部分会使用严格模式来限制程序开发者。 
对于文件访问在Android 7.0以前可以使用file://uri的方式访问,但是这个地方有个问题,就是即使不是你自身应用产生的文件,只要知道对方的uri则就可以调用到,这样在安全性上就产生了风险。所以Android 7.0后新增了对文件跨进程访问的限制,这个限制会造成,如果使用file://uri的方式访问,则会出现android.os.FileUriExposedException的异常。

FileProvider 使用

Step 1 AndroidManifest ,注册FileProvider

 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
...>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="org.unreal.update"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/update_files" />
</provider>
...
</application>
</manifest>

需要注意的地方是 
android:authorities 参数,如同ContentProvider,此处需要你提供一个uri的authorities,以便于content://android:authorities/uri访问到,android:authorities可以随意定义

Step 2 res下创建xml文件夹,并在xml文件夹下创建update_files.xml

<resources xmlns:android="http://schemas.android.com/apk/res/android">
<paths>
<files-path path="files" name="files" />
<cache-path path="files" name="cache" />
<external-path path="files" name="external" />
<external-files-path path="files" name="externalfiles"/>
<!-- 此标签需要 support 25.0.0以上才可以使用-->
<external-cache-path path="files" name="externalcache"/>
</paths>
</resources>

name:名称标志字符串,不可以同名! 
path:文件夹“相对路径”,完整路径取决于当前的标签类型。

标签 路径
…….. * 代表 当前文件夹及其子文件夹
file-path 物理路径为Context.getFilesDir() + /files/*
cache-path 物理路径为Context.getCacheDir() + /files/*
external-path 物理路径为Environment.getExternalStorageDirectory() + /files/*
external-files-path 物理路径为Context.getExternalFilesDir(String) + /files/*
external-cache-path 物理路径为Context.getExternalCacheDir() + /files/*

在简书看到 zhuhf 大神的关于FileProvider的文章后,发现还有一个隐藏的标签

文章地址: http://www.jianshu.com/p/55eae30d133c

<root-path name="name" path="path" />
标签 路径
…….. * 代表 当前文件夹及其子文件夹
root-path 物理路径相当于 /path/*

Step 3 通过getUriForFile获取到uri

data = FileProvider.getUriForFile(context,"之前在AndroidManifest中配置的android:authorities", "7.0后文件的路径");
// 给目标应用一个临时授权
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

FLAG_GRANT_READ_URI_PERMISSION:表示读取权限; 
FLAG_GRANT_WRITE_URI_PERMISSION:表示写入权限; 
根据你的需求,是读取呢,还是写入自行选择

例子 安装APK

private void installApk(File apk) {
if (!apk.exists()) {
return;
}
Uri data;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// UpdateConfig.FILE_PROVIDER_AUTH 即是在清单文件中配置的authorities
data = FileProvider.getUriForFile(context, UpdateConfig.FILE_PROVIDER_AUTH, apk);
// 给目标应用一个临时授权
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
data = Uri.fromFile(apk);
}
intent.setDataAndType(data, "application/vnd.android.package-archive");
context.startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}

Android 7.0 FileProvider 使用说明的更多相关文章

  1. android 7.0+ FileProvider 访问隐私文件 相册、相机、安装应用的适配

    从 Android 7.0 开始,Android SDK 中的 StrictMode 策略禁止开发人员在应用外部公开 file:// URI.具体表现为,当我们在应用中使用包含 file:// URI ...

  2. Android 7.0 通过FileProvider共享文件

    一.概述 Android 7.0后,提供了很多新特性,其中最主要的是禁止了通过file://URI直接在文件操作共享文件(该操作会触发FileUriExposedException),而是通过cont ...

  3. android 7.0 应用间文件共享FileProvider

    1.官方教程 Android 7.0 以后安全系数提高,应用间文件共享要使用FileProvider.原来的 file:/// Uri 替换为 content://Uri  https://devel ...

  4. 关于Android 7.0(API24)相机的问题汇总

    在开发Android项目的时候,我们会用到相机,有些时候只是开发一个普通的扫码,仅仅赋予一下 权限 就好了,但是有些时候是需要拍照和从相册中获取照片的.我们在Android 5.0以及5.0之前调用相 ...

  5. Android开发之深入理解Android 7.0系统权限更改相关文档

    http://www.cnblogs.com/dazhao/p/6547811.html 摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限 ...

  6. Android 8.0+ 更新安装apk失败的问题

    最近做项目发现Android 8.0+ 更新安装apk时 出现安装失败的情况  总结原因是 缺少安装的权限 Android 8.0 (Android O)为了针对一些流氓软件引导用户安装其他无关应用. ...

  7. Android 7.0下,拍摄照片报错

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

  8. android 7.0以上共享文件(解决调用系统照相和图片剪切出现的FileUriExposedException崩溃问题)

    在android7.0开始试共享“file://”URI 将会导致引发 FileUriExposedException. 如果应用需要与其他应用共享私有文件,则应该使用 FileProvider, F ...

  9. Android 7.0+相机、相册、裁剪适配问题

    Android 7.0+相机.相册.裁剪适配问题 在manifest中: <provider android:name="android.support.v4.content.File ...

随机推荐

  1. STL中的内存与效率

    STL中的内存与效率 1. 使用reserve()函数提前设定容量大小,避免多次容量扩充操作导致效率低下.  关于STL容器,最令人称赞的特性之一就是是只要不超过它们的最大大小,它们就可以自动增长到足 ...

  2. 用 PHP 编写 http 服务器

    概述 众所周知,我们一般使用 PHP 开发Web程序时需要使用到比如Apache或Nginx等Web服务器来支持,那么有没有办法直接使用PHP开发HTTP服务器,答案当然是可以的,最近看了一遍Work ...

  3. kafka不停止服务的情况下修改日志保留时间

    kafka配置文件如下: broker.id=1 port=9092 host.name=ssy-kafka1 num.network.threads=4 num.io.threads=8 socke ...

  4. 开源的前端web框架推荐

    B-JUI前端框架:http://demo.b-jui.com/ gentelella :https://colorlib.com/polygon/gentelella/ admui(收费):http ...

  5. 国内云计算的缺失环节: GPU并行计算(转)

    [IT时代周刊编者按]云计算特有的优点和巨大的商业前景,让其成为了近年来的IT界最热门词汇之一.当然,这也与中国移动互联网的繁荣紧密相关,它们需要有相应的云计算服务作为支撑.但本文作者祁海江结合自身的 ...

  6. 在sqlite中,如何删除字段? how to drop a column in sqlite

    在sqlite中可以使用ALTER TABLE语法对表结构进行修改,从官方的文档说明中,语法如下图: 从图中可以看出,ALTER TABLE仅仅支持表名重命名,添加字段,却没有删除字段的方法.那么该如 ...

  7. C++实现排序算法

    稳定性:快速 希尔 选择 堆排序不稳定 时间复杂度:平均情况下,快速.希尔.归并和堆排序的时间复杂度均为O(nlog2(n)),其他都是O(n^2).最坏情况下,快排的时间复杂度为O(n^2) #in ...

  8. 异常测试之Socket网络异常

    本文由作者张雨授权网易云社区发布. 前言 不知道大家在测试的过程中有没有发现关于异常测试这样一个特点: 无论是分散在功能测试中的异常用例还是规模相对较大的专项异常测试中,异常测试的用例占比虽然不大但是 ...

  9. JAVA 定时器时间格式

    格式: [秒] [分] [小时] [日] [月] [周] [年] 通配符说明: \*:表示所有值.例如:在分的字段上设置"\*",表示每一分钟都会触发. ?:表示不指定值.使用的场 ...

  10. C++ const 和static的总结以及使用

    一  static的使用 (作用域和存储方式) 1.作用域---------->隐藏 静态函数跟静态全局变量的作用类似 (静态函数不能被其它文件所用: 其它文件中可以定义相同名字的函数,不会发生 ...