概述
Android 7以后对于应用之间的文件访问做了限制,不再支持跨应用之间的 file:/// 格式文件访问,文件访问需要使用 content:/// 格式,官方推荐我们使用 FileProvider 来完成跨应用文件的读写。
使用
使用步骤:
- manifest中声明 FileProvider
- res/xml中定义对外暴露的文件夹路径
- 生成content://类型的Uri
- 给Uri授予临时权限
- 使用Intent传递Uri
1 | <provider |
这里 android:exported
和 android:grantUriPermissions
必须设置为 false和true,否则编译时会抛出 SecurityException。后面源码分析会解释。
1 | <?xml version="1.0" encoding="utf-8"?> |
name 是生成的 uri 中指代路径名称,path 是实际的路径名称。
paths 属性支持的类型在 FileProvider 源码中可以找到:
1 | String TAG_ROOT_PATH = "root-path"; // new File("/") |
1 | Intent intent = new Intent("****"); |
被启动的应用拿到文件流之后就可以对文件进行操作了,包括读和写。
1 | InputStream in = context.getContentResolver().openInputStream(uri); |
源码分析
FileProvider
是继承自 ContentProvider
。
1 | public class FileProvider extends ContentProvider { |
对于增删改查接口仅支持 query
和 delete
、以及 openInputStream
和 openOutputStream
。
另外在 attachInfo 方法中检查了 exported
和 grantUriPermissions
属性:
1 | @Override |
说明 FileProvider 不是公开的,不能像普通的 ContentProvider 那样的方式被外界的程序使用。