一、权限更改
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。
要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。也就是说,对于应用间共享文件这块,Android N中做了强制性要求
来看一段代码
String cachePath = getApplicationContext().getExternalCacheDir().getPath();
File picFile = new File(cachePath, "test.jpg");
Uri picUri = Uri.fromFile(picFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, picUri);
startActivityForResult(intent, 100);
这是常见的打开系统相机拍照的代码,拍照成功后,照片会存储在picFile文件中。
这段代码在Android 7.0之前是没有任何问题,但是如果你尝试在7.0的系统上运行,会抛出FileUriExposedException异常。
使用FileProvider
FileProvider使用大概分为以下几个步骤:
- manifest中申明FileProvider
- res/xml中定义对外暴露的文件夹路径
- 生成content://类型的Uri
- 给Uri授予临时权限
- 使用Intent传递Uri
1.manifest中申明FileProvider:
<manifest>
...
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.demo.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths" />
</provider>
...
</application>
</manifest>
android:name:provider你可以使用v4包提供的FileProvider,或者自定义的,只需要在name申明就好了,一般使用系统的就足够了。
android:authorities:类似schema,命名空间之类,后面会用到。
android:exported:false表示我们的provider不需要对外开放。
android:grantUriPermissions:申明为true,你才能获取临时共享权限。
2. res/xml中定义对外暴露的文件夹路径:
新建paths.xml,文件名随便起,后面会引用到。
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_images" path="images"/>
</paths>
name:一个引用字符串。
path:文件夹“相对路径”,完整路径取决于当前的标签类型。
path可以为空,表示指定目录下的所有文件、文件夹都可以被共享。
paths这个元素内可以包含以下一个或多个,具体如下: