FileProvider解决FileUriExposedException

原创 2017年09月07日 10:53:31

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类型的Uri
        data = 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 - 安卓开发技术分享
             扫描二维码加关注

Android开发666

版权声明:本文为博主原创文章,未经博主允许不得转载。

FileProvider文件共享FileUriExposedException异常解决

FileProvider是一个特殊的ContentProvider子类,它将 content:// Uri 代替了 file:/// Uri ,从而促进与应用程序关联的文件的安全共享. 官方文档 ...
  • qq_25804863
  • qq_25804863
  • 2016年04月02日 11:53
  • 598

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

一.前言 从 Android N(7.0) 开始,将严格执行 StrictMode 模式,也就是说,将对安全做更严格的校验。而从 Android N 开始,将不允许在 App 间,使用 file:/...
  • qq_38208201
  • qq_38208201
  • 2017年08月01日 15:07
  • 355

Android笔记:Android 7.0 FileUriExposedException 解决

Android7.0 异常 FileUriExposedException
  • xiaoyu940601
  • xiaoyu940601
  • 2017年01月13日 11:05
  • 7353

Android 7.0 安装Apk时报错FileUriExposedException 解决

安装Apk时报错FileUriExposedException 1、AndroidManifest.xml写入 public class DialogUtils { public static v...
  • zuiaisha1
  • zuiaisha1
  • 2017年02月11日 20:46
  • 1612

完美解决主工程与lib库的provider冲突

1.问题在android系统6.0以上的系统对权限的管理越来越严格了,特别是存储权限,需要通过FileProvider来读写文件,或许很多朋友像我一样都遇到过主工程与lib库的provider冲突,导...
  • hmmhhmmhmhhm
  • hmmhhmmhmhhm
  • 2017年05月31日 18:53
  • 1939

安卓下的文件分享——FileProvider

分享文件 △概述:如果你要对外提供少量数据,你可以用Intent带着少量数据出去,当你需要对外提供大批量的数据(比如一个图片编辑软件向你请求 一个图片资源,一个文档编辑器向你请求一个文档)你将需要分享...
  • u010707039
  • u010707039
  • 2015年05月04日 21:47
  • 1516

Uri权限问题&&FileProvider学习

今天用andriod 6.0的手机运行某个项目,进入主页面弹出更新弹窗,点击更新,发现任务栏下载完毕后点击安装时崩溃了,也没有错误日志,搜了半天终于发现问题所在。原来,从android 7.0开始,不...
  • sqf251877543
  • sqf251877543
  • 2017年06月30日 14:25
  • 225

android N FileProvider使用方法

Android N API的变化之FileProvider.
  • u010152805
  • u010152805
  • 2017年09月15日 11:36
  • 254

Android7.0拍照失败FileUriExposedException,你的拍照代码升级了吗

背景: SamSung SM-N9006 Android5.0在应用中拍照之后,无法获取拍照之后的数据,报错FileUriExposedException 思路:参考官方文档对该错误的解释,是由于...
  • yunboxiang
  • yunboxiang
  • 2017年01月04日 11:11
  • 3781

Android主工程与依赖库的FileProvider冲突的问题

在Android7.0版本中,为了安全的考虑引入了FileProvider类,所以这就造成我们的主工程和依赖库中都有可能使用了FileProvider的相关引用在AndroidManifest文件中引...
  • weixue9
  • weixue9
  • 2017年10月26日 14:45
  • 152
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:FileProvider解决FileUriExposedException
举报原因:
原因补充:

(最多只允许输入30个字)