二:Android 7.0权限 FileProvider 使用及异常总结

一:FileProvider

为什么Android 7.0 文件共享要使用FileProvider

这个原因是因为,Android 7.0 版本以后,对于StrictMode的审查又严格了一步,就如在Android 3.0以后加入的NetWorkOnMainThread的异常一样,Google对于会对Android系统造成体验或者安全问题的部分会使用严格模式来限制程序开发者。 
对于文件访问在Android 7.0以前可以使用file://uri的方式访问,但是这个地方有个问题,就是即使不是你自身应用产生的文件,只要知道对方的uri则就可以调用到,这样在安全性上就产生了风险。所以Android 7.0后新增了对文件跨进程访问的限制,这个限制会造成,如果使用file://uri的方式访问,则会出现android.os.FileUriExposedException的异常。

二:使用步骤

  • manifest中声明FileProvider
  • res/xml中定义对外暴露的文件夹路径
  • 生成content://类型的Uri
  • 给Uri授予临时权限
  • 使用Intent传递Uri
  • 异常总结
  • 有关此文章见 https://blog.csdn.net/Lj_18210158431/article/details/92983558

三:AndroidManifest.xml文件声明


com.dintech.app.nameplate">







   



com.dintech.app.nameplate"
        android:exported="false"
        android:grantUriPermissions="true">
        @xml/filepaths" />



四:在res目录下新建一个xml文件夹,并且新建一个filepaths的xml文件



    

五:修改代码

//判断版本 如果在Android7.0以上,使用FileProvider获取Uri
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Uri contentUri = FileProvider.getUriForFile(PersonalCenterActivity.this, getPackageName(), avatarUrl);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
} else {
    //否则使用Uri.fromFile(file)方法获取Uri
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(avatarUrl));
}

六:异常总结

 佳姝1:Android 7.0调用相机时异常

android.os.FileUriExposedException: file:///storage/emulated/0/photo.jpeg exposed beyond app through ClipData.Item.getUri()

二:Android 7.0权限 FileProvider 使用及异常总结_第1张图片

原因:

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

解决方案一:具体FileProvider配置在前方

AndroidManifest.xml中添加provider

解决方案二在Application的onCreat()方法中添加以下代码:

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();

 佳姝2:  异常:java.lang.SecurityException: Provider must not be exported

解决方案:android:exported必须设置成false

 佳姝3:异常: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()一样。

以上总结笔记为私有的。

 

你可能感兴趣的:(二:Android 7.0权限 FileProvider 使用及异常总结)