Android7.0读取图片导致Uri.fromFile(File)报错
我在学习Android中Camera的时候发现,如果我们想要原图,直接读取图片位置显示的时候程序直接崩溃了,我发现报了下面这个错误:
android.os.FileUriExposedException: file:///storage/emulated/0/temp.png exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1958)
at android.net.Uri.checkFileUriExposed(Uri.java:2348)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:941)
…
然后我在百度上发现是Android7.0更新对于Uri的判断,不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法。
原因在于使用file://Uri会有一些风险,比如:
因此,google提供了FileProvider,使用它可以生成content://Uri来替代file://Uri。
接下来我们来说在代码中我们怎么进行操作吧:
第一步:在AndroidManifest.xml中加上摄像头、读写磁盘的权限:
第二步:在AndroidManifest.xml中加上自定义权限的ContentProvider:
我们来解释一下里面的各个属性吧:
android:name="android.support.v4.content.FileProvider"provider你可以使用v4包提供的FileProvider,或者自定义您自己的,只需要在name申明就好了,一般使用系统的就足够了。 android:authorities="你的包名.FileProvider"自定义的权限,类似命名空间 android:exported="false"是否设置为独立进程 android:grantUriPermissions="true"是否拥有共享文件的临时权限 android:resource="@xml/自定义名字"共享文件的文件根目录,名字可以自定义
第三步:在项目res目录下创建一个xml文件夹,里面创建一个和上面自定义名字一样的.xml文件:
第三步:在项目res目录下创建一个xml文件夹,里面创建一个和上面自定义名字一样的.xml文件:
解释一下属性:
name="自定义名字" 一个引用字符串 path="."文件夹“相对路径”,完整路径取决于当前的标签类型。(path可以为空,表示指定目录下的所有文件、文件夹都可以被共享)
第四步:在代码中将Uri.fromFile替换:
第四步:在代码中将Uri.fromFile替换:
if (Build.VERSION.SDK_INT >= 24) { uri = FileProvider.getUriForFile(this,"com.gin.xjh.camera.provider", new File(mFilePath)); } else { uri = Uri.fromFile(new File(mFilePath)); }
这样就可以代替Uri.fromFile(File)的作用了。
但是我们要注意以下的几个问题:
provider需要保证唯一性,即在不同的app里面需要使用不同的名称(建议:项目名+provider) 如果两个项目使用了同一个provider,真机上无法装载 注意代码里面的provider名字需要和清单的provider名字一致,否则会报空
上一篇: javaScript中的空值和假值
下一篇: 静默安装oracle11g