FileProvider使用(拍照、安装APP、共享文件)

FileProvider

在Android7.0及之后我们无法直接将一个FileUri共享给另一个程序进行使用。系统会抛出一个异常FileUriExposedException。官方是这样描述的:

The exception that is thrown when an application exposes a file:// Uri to another app.

当一个应用程序暴漏一个file:// Uri给另一个app时就会抛出这个异常。

This exposure is discouraged since the receiving app may not have access to the shared path. For example, the receiving app may not have requested the Manifest.permission.READ_EXTERNAL_STORAGE runtime permission, or the platform may be sharing the Uri across user profile boundaries.

由于需要接收fileURI的应用程序可能无法访问共享的路径,因此不建议这样做。这可能是由于使用了Manifest.permission.READ_EXTERNAL_STORAGE权限导致,或者平台可以跨越用户配置边界共享Uri。

PS:这个很好理解,比如说我有一个app被装在了手机上,但是没有申请READ_EXTERNAL_STORAGE权限(6.0后需要动态申请),但是我在另一个程序中请求这个app来读取这个文件是不是就会出现问题了,肯定就会出现异常了。所以说使用了内容提供程序,数据的读取是由内容提供者进行读取的,这样就要求数据提供者必须具有这个权限,也保证了数据安全。

Instead, apps should use content:// Uris so the platform can extend temporary permission for the receiving app to access the resource.

我们应该使用content:// Uris对其进行替换,以便平台可以为需要访问特定资源的app扩展临时权限。

This is only thrown for applications targeting Build.VERSION_CODES#N or higher. Applications targeting earlier SDK versions are allowed to share file:// Uri, but it’s strongly discouraged.

这个异常只会在目标版本大于等于7.0时抛出。之前的版本可以继续使用fileURI,不过不推荐这样做。

这些都是由于7.0开启了严格模式(StrictMode)造成的,官方在7.0的变更中是这么说的:

对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。

FileProvider类的继承关系

java.lang.Object
   	android.content.ContentProvider
 	   	android.support.v4.content.FileProvider

官方介绍

FileProvider is a special subclass of ContentProvider that facilitates secure sharing of files associated with an app by creating a content:// Uri for a file instead of a file:/// Uri.

FileProviderContentProvider的子类,它通过为一个文件创建content:// Uri 来替换file:/// Uri,以此来达到文件的安全共享。

核心步骤

1、定义FileProvider

2、定义可用的文件路径

3、为定义的FileProvider添加文件路径

4、为特定文件生成ContentURI

5、授予ContentURI授予临时权限

1、定义FileProvider

由于FileProvider提供了ContentURI的生成方法,所以我们无需在代码中定义写一个它的子类。以下代码中的name属性是固定的,authorities可以自己定义,一般是包名字加上.fileprovider。exported设置为false,因为通常是拒绝外部直接访问的。grantUriPermissions需要为true,需要授予临时的Uri权限。

<manifest>
    ...
    <application>
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            ...
        </provider>
        ...
    </application>
</manifest>

2、定义可用的文件路径

FileProvider只能为预先指定的目录中的文件生成可用的ContentURI。要指定目录,需要使用<paths>

该文件需要建立在res目录下名为xml的目录下,xml目录需要自己建立。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--定义APP的存放目录-->
    <external-path
        name="AppInstaller"
        path="/Download"></external-path>
</paths>

paths下可以包含一个或者多个子节点。

<root-path/> 代表设备的根目录new File("/");//很少用
//app内部存储
<files-path/> 代表context.getFilesDir()
<cache-path/> 代表context.getCacheDir()
//sd卡存储
<external-path/> 代表Environment.getExternalStorageDirectory()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值