问题1.android 7.0 因为file://引起的FileUriExposedException异常
7.0以前的版本
String path = ImageUtil.getSDCardPath();
File file = new File(path + "/" + System.currentTimeMillis() + ".jpg");
imageUri = Uri.fromFile(file);
这个file文件直接非常简单的转换成uri格式
android.os.FileUriExposedException: file:///XXX exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
7.0之后的版本
当把targetSdkVersion指定成24及之上并且在API>=24的设备上运行时。这种方式则会出现FileUriExposedException异常
原因:
Android不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法。原因在于使用file://Uri会有一些风险,比如:
文件是私有的,接收file://Uri的app无法访问该文件。在Android6.0之后引入运行时权限,如果接收file://Uri的app没有申请READ_EXTERNAL_STORAGE权限,在读取文件时会引发崩溃。
因此,google提供了FileProvider,使用它可以生成content://Uri来替代file://Uri。
解决方案:
首先在AndroidManifest.xml中添加provider android:authorities是用来标识provider的唯一标识,在同一部手机上一个"authority"串只能被一个app使用,冲突的话会导致app无法安装。
android:exported必须设置成false,后面异常会讲为什么android:grantUriPermissions用来控制共享文件的访问权限,也可以在java代码中设置。
<!--处理7.0以上获取拍照相册uri兼容问题-->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.glorystudent.golflife.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
添加在<application 之内
@xml/provider_paths 这是指定路径和转换规则:res/xml/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="diary sdcard/photo"/>
<external-path path="" name="camera_photos" />
<external-path name="my_images" path="Android/data/com.example.wmz.network/files/Pictures/" />
<external-path name="images" path="Pictures/" />
<external-path name="dcim" path="DCIM/" />
<root-path
name="root_path"
path="." />
</paths>
修改代码:
imageUri = FileProvider.getUriForFile(this, FriendChatActivity.this.getPackageName() + ".fileprovider", file);
可能出现的问题:
1.java.lang.SecurityException: Provider must not be exported
解决方案:android:exported必须设置成false
2.Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
解决方案:AndroidManifest.xml处的android:authorities必须跟mActivity.getPackageName() + ".fileprovider"一样