FileUriExposedException

在给app做版本升级的时候,先从服务器下载新版本的apk文件到sdcard路径,然后调用安装apk的代码,一般写法如下:

private void openAPK(String fileSavePath){File file=new File(fileSavePath);Intent intent = new Intent(Intent.ACTION_VIEW);Uri data = Uri.fromFile(file);intent.setDataAndType(data, "application/vnd.android.package-archive");startActivity(intent);
}

这样的写法在Android7.0版本之前是没有任何问题,只要给一个apk文件路径就能打开安装。但是在Android7.0版本上会报错:

 android.os.FileUriExposedException:file:///storage/emulated/0/Download/FileProvider.apk exposed beyond app through Intent.getData()

从Android 7.0开始,一个应用提供自身文件给其它应用使用时,如果给出一个file://格式的URI的话,应用会抛出FileUriExposedException。这是由于谷歌认为目标app可能不具有文件权限,会造成潜在的问题。所以让这一行为快速失败。

FileProvider方式解决

这是谷歌官方推荐的解决方案。即使用FileProvider来生成一个content://格式的URI。

1.在Manifest.xml中声明一个provider。

<application ···>···<provider
        android:name="android.support.v4.content.FileProvider"android:authorities="com.ansen.fileprovider.fileprovider"android:grantUriPermissions="true"android:exported="false"><meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider>
</application>

android:name值是固定的,android:authorities随便写但是必须得保证唯一性,我这边用的是包名+”fileprovider”,android:grantUriPermission跟android:exported固定值。

里面包含一个meta-data标签,这个标签的name属性固定写法,android:resource对应的是一个xml文件。我们在res文件夹下新建一个xml文件夹,在xml文件夹下新建file_paths.xml文件。内容如下:

<?xml version="1.0" encoding="utf-8"?>
<paths><external-path name="name" path="Download"/>
</paths>

name表示生成URI时的别名,path是指相对路径。

paths标签下的子元素一共有以下几种:

files-path 对应  Context.getFilesDir()
cache-path 对应  Context.getCacheDir()
external-path 对应 Environment.getExternalStorageDirectory()
external-files-path 对应  Context.getExternalFilesDir()
external-cache-path 对应  Context.getExternalCacheDir()

2.当然我们还需要修改打开apk文件的代码

首先判断下版本号,如果手机操作系统版本号大于等于7.0就通过FileProvider.getUriForFile方法生成一个Uri对象。

private void openAPK(String fileSavePath){File file=new File(fileSavePath);Intent intent = new Intent(Intent.ACTION_VIEW);Uri data;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0// "com.ansen.fileprovider.fileprovider"即是在清单文件中配置的authorities// 通过FileProvider创建一个content类型的Uridata = FileProvider.getUriForFile(this, "com.ansen.fileprovider.fileprovider", file);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 给目标应用一个临时授权} else {data = Uri.fromFile(file);}intent.setDataAndType(data, "application/vnd.android.package-archive");startActivity(intent);
}

源码下载

如果你想第一时间看我的后期文章,扫码关注公众号,每周不定期推送Android开发实战教程文章…

      Android开发666 - 安卓开发技术分享扫描二维码加关注

FileProvider解决FileUriExposedException相关推荐

  1. Android 7.0配置fileprovider共享文件 解决FileUriExposedException

    一.前言 从 Android N(7.0) 开始,将严格执行 StrictMode 模式,也就是说,将对安全做更严格的校验.而从 Android N 开始,将不允许在 App 间,使用 file:// ...

  2. [转]快速使用FileProvider解决Android7.0文件权限问题

    升级到Android7.0之后,启动系统相机或者截图,传入URI的时候可能会导致程序闪退崩溃.这是因为7.0的新的文件权限导致的.下面是解决这个问题的快速解决方案. 问题代码 在7.0可能会出问题的代 ...

  3. Android 7.0 行为变更 通过FileProvider在应用间共享文件吧

    本文转自张鸿洋的博客 http://blog.csdn.net/lmj623565791/article/details/72859156 一.概述 之前项目的新特性适配工作都是同事在做,一直没有怎么 ...

  4. android开发 文件分享到应用,Android开发之——7.0适配之应用之间共享文件(FileProvider)...

    前言 Android 7.0强制启用了被称作StrictMode的策略,带来的影响就是你的App对外无法暴露file://类型的URI了. 如果你使用Intent携带这样的URI去打开外部App(比如 ...

  5. Android 7.0下拍照和裁剪图片

    Android 7.0下拍照和裁剪图片 最近,公司的APP集中爆发了头像上传中拍照或照片裁剪的bug,让我才意识到及时学习Android新特性是多么重要,一个过去式的APP是无法一直满足日益变化的新需 ...

  6. Android 7.0下载安装APK

    Android 7.0下载安装APK 这里只说安装,不说下载.因为下载网上一搜一大堆,暂且说下一下Android7.0 下载安装APK时的兼容性问题. 简介 随着Android版本越来越高,Andro ...

  7. Android7.0 拍照 选择照片 权限 实现

    参考链接: http://blog.csdn.net/hu5080126/article/details/53738625 http://www.jianshu.com/p/ba57444a7e69 ...

  8. android调用另一app的xml,Android 7.0+调用其他App打开文件

    ​ 近期需要用到读取Android设备外存中的JSON和Word,在前期开发时用于调试的是Android 6.0的米4,当拿到实际应用环境(Android 7.0)时,Android 6.0之后的版本 ...

  9. android 读取wps_Android 默认使用wps打开本地文档

    最近开发一个需求是使用wps打开本地的文档,所以记录一下方便以后查阅 对于Android 7.0 以后文件的读写 请参照一下链接 https://www.jianshu.com/p/5ebfa842e ...

最新文章

  1. 剑指offer之51-55题解
  2. SAP云平台上的ABAP编程环境能做哪些事情
  3. vs里根据json快速创建对应类的方法
  4. 全网最详细 Python如何读取NIFTI格式图像(.nii文件)和 .npy格式文件和pkl标签文件内容
  5. linux系统mysql密码忘记了怎么办_Linux系统下忘记MySql密码怎么办
  6. arcgis flexviewer中由Application向widget传值
  7. SpringBoot源码分析解答问题
  8. 基于机器视觉的玻璃Mark点字符识别
  9. html自适应布局源码,手机端页面自适应解决方案—rem布局进阶版(附源码示例)...
  10. 关于目标文件系统,文件过大的解决方法
  11. jQuery初学笔记一,美元符号$
  12. 网络广告计费方式CPM、CPA、CPS、CPT、CPC及比较分析
  13. U-Boot下的I2C设备的读写
  14. 前端基础总结--CSS
  15. STM32F103ZG单片机解密确保成功 ST芯片解密
  16. SQL注入(基于 tryhackme 的讲解)
  17. TZT3801G无线振弦在线监测系统
  18. redis expire方式设置缓存时间的坑
  19. raw/rgb/yuv/nv21图像格式总结
  20. Windows10企业英文版下载 2022-2-17更新

热门文章

  1. JavaSE 多态 抽象类 接口
  2. 10分钟设置自己专属的域名邮箱,逼格满满!
  3. K8S集群中Pod资源处于Pending状态排查思路
  4. C++修炼之筑基期第四层 ——透过日期类看运算符重载 | 赋值运算符重载 | 取地址操作符重载
  5. scanpst修复outlook收件箱
  6. e.preventDefault()与return false的区别
  7. DRG/DIP支付方式改革,助力“医保患企”进入快车道!
  8. linux 授予用户权限
  9. Python3.7中time模块的time()、perf_counter()和process_time()的区别
  10. Processing——A Music Game for the Avengers