最近作者又碰到因为android 7.0 引起的兼容问题了。

在7.0以前的版本:
//创建临时图片
File photoOutputFile = SDPath.getFile("temp.jpg", SDPath.PHOTO_FILE_STR);
Uri photoOutputUri = Uri.fromFile(photoOutputFile);

这个file文件直接非常简单的转换成"file://XXX/XXX/XXX"的uri格式

7.0后的版本:

当把targetSdkVersion指定成24及之上并且在API>=24的设备上运行时。这种方式则会出现FileUriExposedException异常

android.os.FileUriExposedException:         file:///XXX exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:)
at android.net.Uri.checkFileUriExposed(Uri.java:)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:)
at android.content.Intent.prepareToLeaveProcess(Intent.java:)
...
原因

Android不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法。

原因在于使用file://Uri会有一些风险,比如:

  • 文件是私有的,接收file://Uri的app无法访问该文件。
  • 在Android6.0之后引入运行时权限,如果接收file://Uri的app没有申请READ_EXTERNAL_STORAGE权限,在读取文件时会引发崩溃。

因此,google提供了FileProvider,使用它可以生成content://Uri来替代file://Uri

解决方案

首先在AndroidManifest.xml中添加provider

  • android:authorities
    是用来标识provider的唯一标识,在同一部手机上一个"authority"串只能被一个app使用,冲突的话会导致app无法安装。
  • android:exported必须设置成false,后面异常会讲为什么
  • android:grantUriPermissions用来控制共享文件的访问权限,也可以在java代码中设置。
因此,google提供了FileProvider,使用它可以生成content://Uri来替代file://Uri。

解决方案
首先在AndroidManifest.xml中添加provider android:authorities
是用来标识provider的唯一标识,在同一部手机上一个"authority"串只能被一个app使用,冲突的话会导致app无法安装。
android:exported必须设置成false,后面异常会讲为什么
android:grantUriPermissions用来控制共享文件的访问权限,也可以在java代码中设置。
解决方案

首先在AndroidManifest.xml中添加provider

  • android:authorities
    是用来标识provider的唯一标识,在同一部手机上一个"authority"串只能被一个app使用,冲突的话会导致app无法安装。
  • android:exported必须设置成false,后面异常会讲为什么
  • android:grantUriPermissions用来控制共享文件的访问权限,也可以在java代码中设置。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.zhongjh.phone.ui"
··· <provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.zhongjh.phone.ui.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider> </manifest >

res/xml/provider_paths.xml
这是指定路径和转换规则
<paths>中可以定义以下子节点

子节点 对应路径 例子
files-path Context.getFilesDir()
cache-path Context.getCacheDir()
external-path Environment.getExternalStorageDirectory() /storage/emulated/0/
external-files-path Context.getExternalFilesDir(null)
external-cache-path Context.getExternalCacheDir()

加入我要替换的目录是
/storage/emulated/0/diary sdcard/photo/
那么配置应该写成

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="diary sdcard/photo"/>
</paths>

然后修改代码

//创建临时图片
File photoOutputFile = SDPath.getFile("temp.jpg", SDPath.PHOTO_FILE_STR);
//Uri photoOutputUri = Uri.fromFile(photoOutputFile);
Uri photoOutputUri = FileProvider.getUriForFile(
mContext,
mActivity.getPackageName() + ".fileprovider",
photoOutputFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoOutputUri);
我所碰到的异常处理
  • java.lang.SecurityException: Provider must not be exported
    解决方案:android:exported必须设置成false
  • Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
    解决方案:AndroidManifest.xml处的android:authorities必须跟mActivity.getPackageName() + ".fileprovider"一样

Android 7.0 因为file://引起的FileUriExposedException异常的更多相关文章

  1. Android 7.0 FileProvider 使用说明

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

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

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

  3. android 7.0拍照问题file:///storage/emulated/0/photo.jpeg exposed beyond app through ClipData.Item.getUri

    Android7.0调用相机时出现新的错误: android.os.FileUriExposedException: file:///storage/emulated/0/photo.jpeg exp ...

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

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

  5. Android 7.0系统代码调用安装apk时报错FileUriExposedException完美解决

    项目更新遇到问题   Android项目开发中经常遇到下载更新的需求,以前调用系统安装器执行安装操作代码如下: Intent intent = new Intent(); intent.setActi ...

  6. Android studio3.0打开Device File Explore(文件管理器)的方法(图文教程)

    Android studio3.0打开Device File Explore(文件管理器)的方法(图文教程) 看到网上AS3.0新增加的查看手机文件的新功能,全部都是转载的,没有几个人心细的把如何打开 ...

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

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

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

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

  9. Android 7.0 通过FileProvider共享文件

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

随机推荐

  1. 给GridView设置行高

    近期在工作中遇到了这样一个问题,使用一个GridView展示数据,item中仅仅是一个TextView,可是里面显示的文字多少不固定多少,必须所有展示出来. 遇到的问题: 1.把item中的宽和高设置 ...

  2. 【ios系列】-Quartz 2D常用方法介绍

    Quartz 2D基本介绍 Quartz 2D是一个二维绘图引擎 能够,绘制图形 : 线条\三角形\矩形\圆\弧等,绘制文字,绘制\生成图片(图像),读取\生成PDF,截图\裁剪图片,自定义UI控件( ...

  3. MD5加密解密帮助类

    using System; using System.Security.Cryptography; using System.Text; namespace Maticsoft.DBUtility { ...

  4. Effective JavaScript Item 39 绝不要重用父类型中的属性名

    本系列作为Effective JavaScript的读书笔记. 假设须要向Item 38中的Actor对象加入一个ID信息: function Actor(scene, x, y) { this.sc ...

  5. beego07----web博客

    conf/app.conf appname = blog1 httpport = 8080 runmode = dev name=admin pwd=admin controllersmy/attac ...

  6. java集合的关系

    在 Java2中,有一套设计优良的接口和类组成了Java集合框架Collection,使程序员操作成批的数据或对象元素极为方便.这些接口和类有很多对抽象数据类型操作的API,而这是我们常用的且在数据结 ...

  7. 区块链共识算法 PBFT(拜占庭容错)、PAXOS、RAFT简述

    共识算法 区块链中最重要的便是共识算法,比特币使用的是POS(Proof of Work,工作量证明),以太币使用的是POS(Proof of Stake,股权证明)使得算理便的不怎么重要了,而今PO ...

  8. 路由器的LAN、WAN、WLAN的区别

    路由器的LAN.WAN.WLAN的区别 好多朋友在群内问我路由器如何配置,本来还耐心解答,但是他竟然连LAN.WAN都分不清,瞬间就没了帮助的热情.借这篇经验,小编简单讲一下路由常见的LAN.WAN. ...

  9. python dns server开源列表 TODO

    基于dns lib的,https://github.com/andreif/dnslib 有:https://www.cnblogs.com/anpengapple/p/5664500.html ht ...

  10. springmvc处理ajax跨域

    解决跨域问题:在web.xml中配置corsFilter mvc.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!- ...