一. FileUriExposedException的解决

问题

由于在Android7.0上,google使用了新的权限机制,所以导致在调用相机的时候,如果传递的URI为”file://”类型,的系统会抛出FileUriExposedException这个错误.具体堆栈信息如下:

    android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/***/files/Cache/30001748.jpg exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
at android.net.Uri.checkFileUriExposed(Uri.java:2346)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:832)
at android.content.Intent.prepareToLeaveProcess(Intent.java:8923)
at android.content.Intent.prepareToLeaveProcess(Intent.java:8908)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1519)
at android.app.Activity.startActivityForResult(Activity.java:4288)
...
at android.view.View.performClick(View.java:5611)
at android.view.View$PerformClick.run(View.java:22276)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:6139)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:764)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

解决办法

  1. 解决URI 
    本来是直接通过Uri.fromFile(file)获取的uri,然后通过Intent传出,在Android7.0及以上版本可以采用如下方式获取uri

    // 中间的参数 authority 可以随意设置.
    Uri uri = FileProvider.getUriForFile(context,"org.diql.fileprovider", file);
    • 1
    • 2

    通过这个方法,系统会产生一个临时的uri来进行替换掉原始的uri.

  2. AndroidManifest.xml中配置

    <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="org.diql.fileprovider" //这里就是1中的参数 authority
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/file_paths" />
    </provider>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  3. res中创建相应的文件来让系统最终生成相应的的uri. 
    res的如2中的路径新建对应的文件,这里就是res->xml->file_paths.xml.其中’file_paths.xml’文件的内容如下

    <?xml version="1.0" encoding="utf-8"?>
    <resource xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="cache" path="Cache/" /> //这里的"Cache/"就是问题中抛出异常的那个路径
    </resource>
    • 1
    • 2
    • 3
    • 4

本来以为问题就此解决了,但是又产生了下面的问题

二. IllegalArgumentException: Failed to find configured root that contains …

问题2

java.lang.RuntimeException: Unable to start activity ComponentInfo{.../....EditInfoActivity}: java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/.../files/Cache/30001748.jpg
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2680)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2741)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1492)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:6139)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:764)
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

问题解决

明明这个路径对应的文件是存在的,为什么会找不到呢,感觉到肯定是路径配置那里出问题,经过查找资料,才发现file_paths.xml中配置的external-path是如下作用:

该方式提供在外部存储区域根目录下的文件。它对应Environment.getExternalStorageDirectory返回的路径:eg:”/storage/emulated/0”;

external-files-path的作用是我需要的这种路径即:

该方式提供在应用的外部存储区根目录的下的文件。它对应Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)返回的路径。eg:”/storage/emulated/0/Android/data/com.jph.simple/files”。

将这个修改好之后就一切大工告成了.

参考资料

  1. http://blog.csdn.net/xifengwanzhao/article/details/53587234
  2. FileProvider所支持的几种path类型 http://www.jianshu.com/p/121bbb07cb07

FileUriExposedException_Android7.0适配的更多相关文章

  1. Android权限管理之RxPermission解决Android 6.0 适配问题

    前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...

  2. fir.im Weekly - 关于 Log Guru 开源、Xcode 探索和 Android7.0 适配

    本期 fir.im Weekly 整理了最近的一些技术分享,包括关于 Log Guru 开源.Xcode 探索. Android7.0 适配等等 iOS/Android 相关的工具.源码分享和技术文章 ...

  3. Android7.0适配APK安装

    Android7.0适配APK安装 适配的原因 对于面向Android7.0的应用,Android框架执行的StrictMode API政策禁止在您的应用外部公开file://URL.如果一项包含文件 ...

  4. 【转】Android7.0适配心得

    本文出自:贾鹏辉的技术博客(http://www.devio.org) http://www.devio.org/2016/09/28/Android7.0%E9%80%82%E9%85%8D%E5% ...

  5. Android8.0适配那点事(一)

    最近有小伙伴说,7.0适配整了一波,现在又要来适配8.0,真是一波未平一波又起 但是作为开发者来说,学无止境,不跟上时代的步伐,肯定会被时代所淘汰... 话说Android P已经在路上了,你准备好了 ...

  6. Android8.0适配那点事(二)

    小伙伴们,咱们今天咱继续对Android8.0的适配进行分解,今天将针对启动页,版本适配和系统限制等进行“啃食” 猛戳这里查看Android8.0适配那点事(一): 1.启动页适配 近日,我无意中发现 ...

  7. [转]Android 应用自动更新及6.0,7.0,8.0适配安装

    原贴:https://www.jianshu.com/p/ea42040c7ace 原贴:https://www.jianshu.com/p/ea42040c7ace 原贴:https://www.j ...

  8. Android5.0和Android6.0适配

    gradle配置项 compileSdkVersion 用哪个 Android SDK 版本编译你的应用.因此我们强烈推荐总是使用最新的 SDK 进行编译.在现有代码上使用新的编译检查可以获得很多好处 ...

  9. iOS 10.0适配之旅

    1.升级Xcode体验 升级到Xcode之后,调试程序好多东西都不是太适应 控制台莫名给你打印一堆不是太好理解的东西 之前使用 Alcatraz 下载的插件都不能用(如何使用Alcatraz) 打开麦 ...

随机推荐

  1. MYSQL一次千万级连表查询优化

    概述:交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差,因此SQL优化任务交到了我手上. 这个S ...

  2. Code Signal_练习题_arrayMaxConsecutiveSum

    Given array of integers, find the maximal possible sum of some of its k consecutive elements. Exampl ...

  3. 使用LINQ查询数据实例和理解

    使用LINQ查询数据实例和理解 var contacts= from customer in db.Customers where customer.Name.StartsWith("A&q ...

  4. php实现同一时间内一个账户只允许在一个终端登陆

    在账户表的基础上,我新建了一个账户account_session表,用来记录登录账户的account_id和最新一次登录成功用户的session_id,然后首先要修改登录方法:每次登录成功后,要将登录 ...

  5. linux mysql 卸载与安装及配置命令

    1.RPM包安装方式的MySQL卸载 1) 检查是否安装了MySQL组件. # rpm -qa | grep -i mysql 2)卸载前关闭MySQL服务 # service mysql statu ...

  6. EasyUI 通过 Combobox 实现 AutoComplete 效果

    朋友在做一个web程序,用的EasyUI框架,让我帮忙实现一个自动提示功能.由于之前我也没用过EasyUI框架,就想到了jQueryUI有 AutoComplete 插件,就想直接拿过来用. 但当我将 ...

  7. Windows Win7建立wifi热点,手机共享WIFI上网

    Win7建立wifi热点,手机共享wifi上网 by:授客 QQ:1033553122 1.以管理员身份运行命令提示符:快捷键win+R→输入cmd→回车 2.启用并设定虚拟WiFi网卡:运行命令:n ...

  8. Asp.net MVC检测到有潜在危险的 Request.Form 值

    解决方法很简单,不像网上说的那么麻烦.只需一步: [ValidateInput(false)] public ActionResult Test(){ }

  9. alpha阶段 代码结构及技术难点简介

    我们的产品是安卓端app,所以目前主要就是用Android Studio来进行代码开发. Android Studio的项目的结构还是比较清晰的,如下图,主要就是java文件夹内的代码部分(.java ...

  10. Jenkins 执行python脚本

    操作很简单: * 最新版本的Jenkins,插件管理中下载两个python需要的插: * 重启Jenkins 任务中添加python脚本即可,点击保存时候,自动会在下图中目录生成.py文件 过程如下 ...