android7.0 uri,android 7.0变化之uri的使用(一)

第一篇讲一下android N使用中对于Uri形式读取文件的不同之处。

场景

在使用相机拍照生成头像时,之前的逻辑是,先用intent唤起照相机,并传入一个图片输出的地址,拍摄完毕后,再用intent唤起系统的照片crop,同样传入一个output地址,对相片进行剪辑,最后上传处理完成的照片。

原因分析

在Android N之前,对于Uri形式文件的访问一般采用Uri.fromFile(File file)。但在7.0中,官方对于文件访问的安全性做了提升,禁止向您应用外的app公开 file://URI。也就是系统照片的crop应用无法访问你的照片文件,否则会出现FileUriExposedException异常。详情参阅在应用间共享文件

解决方法

首先在AndroidManifest.xml中声明一个provider

...

...

android:name="android.support.v4.content.FileProvider"

android:authorities="com.your.fileProvider"

android:grantUriPermissions="true"

android:exported="false">

android:name="android.support.FILE_PROVIDER_PATHS"

android:resource="@xml/file_paths" />

...

然后在/res/xml目录下新建一个file_paths.xml,声明需要访问的目录。<?xml version="1.0" encoding="utf-8"?>

name="external_files"

path="." />

其中的元素代表了不同的根目录CellPathfiles-pathContext.getFilesDir().

cache-pathgetCacheDir().

external-pathEnvironment.getExternalStorageDirectory().

external-files-pathContext.getExternalFilesDir(String)

external-cache-pathContext.getExternalCacheDir().

然后使用fileprovider读取文件

原先Uri = Uri.fromFile(new File(strFilePath))

改为现在Uri uri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".fileProvider", new File(strFilePath));

上面解释过了,如果只是在app内读取uri,那么到现在已经完成了,但是如果要调用外部app来访问这个file(例如调用系统的crop对相片进行裁剪),则还需要添加授权操作。具体的操作就是在调用crop前,授予权限。List resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

for (ResolveInfo resolveInfo : resInfoList) {

String packageName = resolveInfo.activityInfo.packageName;

grantUriPermission(packageName, photoUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

}

这里提供了一个较为简便的方法,如果你不知道你所调用的app的包名,可以遍历所有的package,都授予读写权限。

总结

安全性上,android 7.0做了很大的提升,需要开发者多注意。是坑,亦是革新。

备注

在Andorid 7.0系统下,当app对相机和外置储存卡进行使用操作的时候,都需要先请求用户权限,允许以后才可以调用。这个将在下一篇当中讲解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值