Android 应用间共享文件(FileProvider)

在 Android 7.0 中调用系统相机拍照,通过SD卡获取原图,抛出FileUriExposedException异常

从 Android 7.0 开始,应用间共享文件时,如果使用 file://格式的 Uri,就会抛出 FileUriExposedException。
谷歌官方推荐,使用 FileProvider 来生成一个 content://格式的Uri。

FileProvider的使用

1. 在 Manifest 中声明 provider

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.marklei.fileproviderdemo">

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

exported: false 表示 provider 不需要对外开放
grantUriPermissions: true,表示授予 Uri 临时访问权限。

2. res/xml/ 下定义对外暴露的文件夹路径
file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="my_images"
        path="images/" />
</paths>

name: 一个引用字符串。
path: 文件夹“相对路径“,完整路径取决于当前的标签类型。

path 可以为空,表示制定目录下的所有文件、文件夹都可以被共享。

3. 生成 content://类型的 Uri
通过 FileProvider.getUriForFile 来实现:

    File dir = new File(getFilesDir(), "images");
    String fileName = System.currentTimeMillis() + ".jpg";
    File file = new File(dir, fileName);
    Uri uri = FileProvider.getUriForFile(this, "com.marklei.fileproviderdemo", file);

dir: 使用的路径需要和 file_paths.xml 中声明的其中一个相符。
getUriForFile: 第一个参数是Context;第二个参数是在 manifest#provider 中定义的 android:authorities 属性的值;第三个参数是File。

4. 使用 Intent 传递 Uri
调用拍照代码:

    File file = ...;

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    Uri uri = FileProvider.getUriForFile(this, "com.marklei.fileproviderdemo", file);   
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(intent, REQ_CODE);

项目源码:https://github.com/Freakmaster/FileProviderDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值