一.概述

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共享文件的更多相关文章

  1. Android 7.0应用之间共享文件

    原文首发于微信公众号:躬行之,欢迎关注交流! 开发中经常需要将某个文件向另一个应用程序传递,如图片上传到另一个应用程序.文件在不同存储路径之间的复制粘贴等都需要共享文件,可以这样理解接收文件的应用是在 ...

  2. Android 7.0 出现 ”FileUriExposedException“ 和 ”解析包出现错误“ 异常的解决办法

    问题1 :android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.xxx.xxx.xxx.rel ...

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

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

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

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

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

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

  6. Android 7.0 FileProvider 使用说明

    FileProvider FileProvider 这个组件在Android 22.0.0 (也就是 Android 5.0 ) 版本下加入进Android系统,该组件是ContentProvider ...

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

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

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

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

  9. Android 7.0 行为变更

    Android 7.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 如果您之前发布过 Android 应用,请注意 ...

随机推荐

  1. LVS详细介绍以及遇到的坑

    LVS详细介绍以及遇到的坑 一,概述 本文介绍了我搭建LVS集群的步骤,并且在使用LVS(Linux Virtual Server)过程中遇到的问题和坑, 二,LVS简单介绍 大家都知道,LVS中文意 ...

  2. Java面试问题汇总

    转一些面试经验 刚看到下面这份面试清单,从个人的开发面试经历看,里面总结的大部分内容还是很不错的.年后想跳槽的朋友可以选取里面的问题准备一下. GitHub上的面试总结帖 Interview-Note ...

  3. 批处理判断是BIOS还是UEFI启动

    https://files.cnblogs.com/files/liuzhaoyzz/detectefi.rar @echo offpushd %~dp0reg add "HKEY_CURR ...

  4. c#委托之浅析

    前言: 这章我们将弄懂,委托是什么?有什么作用?在什么样的场景下可以启到什么作用? 委托适用的场景:当确定处理一个任务时,不确定其处理任务的方法时可使用,这样可以提高扩展性,调用符合条件的处理方法,避 ...

  5. OPPO R6007在哪里打开usb调试模式的完美流程

    当我们使用Pc接通安卓手机的时候,如果手机没有开启USB开发者调试模式,Pc则无法成功读到我们的手机,遇到此种情况我们需要想方设法将手机的USB开发者调试模式打开,以下内容我们讲解OPPO R6007 ...

  6. web安全类

    web安全类主要分为两个部分:CSRF和XSS 一.CSRF 基本概念:CSRF,通常称为跨站请求伪造,英文名Cross-site request forgery 缩写为CSRF; 怎么防御 1.To ...

  7. C++primer第一章(部分)

    1.4.2 for 语句 for (init-statement; condition; expression) statement; step1:初始化 step2:判断条件,为真则执行循体:为假则 ...

  8. windows短路径转换成长路径

    参考: https://blog.csdn.net/wxqian25/article/details/43951281 https://docs.microsoft.com/en-us/windows ...

  9. 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' ...

  10. Linux SVN 操作详解(转)

    1.将文件checkout到本地目录 svn checkout path(path是服务器上的目录)   例如:svn checkout svn://192.168.1.1/pro/domain    ...