安卓7.0报错android.os.FileUriExposedException

最近在开发过程中遇到了这样一个错误,android.os.FileUriExposedException: file:///storage/emulated/0/xxx/xxx.doc exposed beyond app through Intent.getData()

出现这个问题是在使用Intent附带uri打开sd卡下的doc文件,而在Android 7.0后,应用使用 StrictMode模式,API 禁止向您的应用外公开 file://URI并且使用Intent附带uri访问本地文件时,也是需要经过授权处理的。若要在应用间共享文件,您应发送一项 content://URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider

解决方法

1.在res目录下新建一个xml文件夹,在此文件夹下创建file_path.xml文件(命名任意),文件内容如下

 
 
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android">  <external-path path="." name="external_path"/>  <cache-path path="." name="cache_path" />  <files-path path="." name="files_path" />  <external-files-path path="." name="external_files_path" />  <external-cache-path path="." name="external_cache_path" /> </paths>
path:需要临时授权访问的路径(.代表所有路径) 
name:就是你给这个访问路径起个名字
内部的element可以是files-path,cache-path,external-path,external-files-path,external-cache-path,分别对应Context.getFilesDir(),Context.getCacheDir(),Environment.getExternalStorageDirectory(),Context.getExternalFilesDir(),Context.getExternalCacheDir()等几个方法
 

2.在AndroidManifest.xml的<application></application>标签下新增以下内容:

 
<provider  android:name="android.support.v4.content.FileProvider"  android:authorities="com.example.demo.provider"  android:exported="false"  android:grantUriPermissions="true">  <meta-data  android:name="android.support.FILE_PROVIDER_PATHS"  android:resource="@xml/provider_paths"/> </provider>
 
注意: 
authorities:可以自定义,但为了区分,建议用:app的包名.provider
grantUriPermissions:必须是true,表示授予 URI 临时访问权限 
exported:必须是false 
resource:中的@xml/file_paths是我们接下来要添加的文件
 

3.在使用Intent打开文件时,做如下判断

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
Uri uri = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    //第二个参数是manifest中定义的`authorities`
    uri = FileProvider.getUriForFile(context, "com.example.demo.provider", new File(param));
} else {
    uri = Uri.fromFile(new File(param));
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
intent.setDataAndType(uri, "image/*");
context.startActivity(intent);
 
 
 
 
 
 
 
 
 
 

猜你喜欢

转载自blog.csdn.net/gs12software/article/details/77676970