FileUriExposedException异常解决方案

遇到的一个异常
FileUriExposedException异常
翻看Google的异常文档:
https://developer.android.google.cn/reference/android/os/FileUriExposedException.html

在7.0及以后开始
应用程序向另一个应用程序公开时引发的异常。file://Uri
由于接收应用程序可能无法访问共享路径, 因此不鼓励此风险敞口。例如, 接收应用程序可能没有请求运行时权限, 或者平台可以共享跨用户配置文件边界。READ_EXTERNAL_STORAGEUri
相反, 应用程序应该使用 uri, 这样平台就可以扩展接收应用程序的临时权限来访问资源。content://
这仅用于针对目标或更高的应用程序。以早期 SDK 版本为目标的应用程序可以共享, 但强烈劝阻。Nfile://Uri
另请参见:
FileProvider
FLAG_GRANT_READ_URI_PERMISSION

使用FileProvider可以解决这个异常:
FileProvider官方文档:
https://developer.android.google.cn/reference/android/support/v4/content/FileProvider.html

1>:在配置文件中声明FileProvider

 
  1. <manifest>

  2. ...

  3. <application>

  4. ...

  5. <provider

  6. android:name="android.support.v4.content.FileProvider"

  7. android:authorities="com.mydomain.fileprovider"

  8. android:exported="false"

  9. android:grantUriPermissions="true">            

  10.             <meta-data

  11.                 android:name="android.support.FILE_PROVIDER_PATHS"

  12.                 android:resource="@xml/file_paths" />

  13. ...

  14. </provider>

  15. ...

  16. </application>

  17. </manifest>

 

android:name 是固定写法
android:authorities 可自定义,是用来标识该provider的唯一标识,建议结合包名来保证authority的唯一性
android:exported 必须设置成 false,否则运行时会报错java.lang.SecurityException: Provider must not be exported 
android:grantUriPermissions 用来控制共享文件的访问权限

<meta-data>节点中的android:resource指定了共享文件的路径。此处的file_paths即是该Provider对外提供文件的目录的配置文件,存放在res/xml/下

 

 

2>配置共享路径

我们在 res/xml/ 的目录下创建 file_paths.xml 文件

 
  1. <paths>

  2. <files-path name="name" path="path"/>

  3. ...

  4. </paths>

其中根元素<paths>是固定的,内部元素可以是以下节点:
<files-path name="name" path="path" /> 对应getFilesDir()。
<cache-path name="name" path="path" /> 对应getCacheDir()。
<external-path name="name" path="path" /> 对应Environment.getExternalStorageDirectory()。
<external-files-path name="name" path="path" /> 对应getExternalFilesDir()。
<external-cache-path name="name" path="path" /> 对应getExternalCacheDir()。

举个栗子:

我将服务器下载的APK文件存储在 sdcard中的Android/data/<package>/files/Download/下
则 xml 的配置是:

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <paths>

  3. <external-files-path path="Download" name="files_path" />

  4. </paths>

3>在代码中调用:

 
  1. private void installAPK(Context context, File file) {

  2. Intent intent = new Intent(Intent.ACTION_VIEW);

  3. Uri data;

  4. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

  5. data = FileProvider.getUriForFile(context, "com.project.pulis.fileprovider",file);

  6. intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

  7. } else {

  8. data = Uri.fromFile(file);

  9. }

  10. intent.setDataAndType(data, "application/vnd.android.package-archive");

  11. startActivity(intent);

  12. }

  13. }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值