Android 7.0应用间文件共享

最近在开发过程中遇到了这样一个错误,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的标签下新增以下内容:

<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/file_path"/>
</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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猫King

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值