Android Programming The Big Nerd Ranch Guide,Second Edition第十六章使用相机Intent部分的改进

来源:互联网 发布:郑秀晶同款淘宝 编辑:程序博客网 时间:2024/05/14 21:20

最近自己在看这本书,看到这部分并亲手上机测试时,发现并不是照书上那样编码之后就能顺利打开相机拍照。经过思考和对比发现:

photoFile文件的转化uri部分编写的不合理。原因:如果运行设备的系统版本低于Android 7.0 ,调用Uri的formFile()方法将File对象转换成Uri对象;否则,就调用FIleProvider的getUriForFIle()方法将File对象转换成一个封装过的Uri对象。getUriForFIle()方法接收三个参数,第一个参数要求传入Context对象,第二个参数可以是任意唯一的字符串,第三个参数则是上面提到过的photoFile(File类型)对象。之所以要进行这样一层转换,是因为从Android 7.0 系统开始, 直接使用本地真实路径的Uri被认为是不安全的,会抛出一个FIleUriExposedException异常。而FileProvider是一种特殊的内容提供器, 它使用了和内容提供器类似的机制来对数据进行保护,可以选择性将封装过的Uri共享给外部, 从而提高了应用的安全性(上述这部分原因解释摘抄自第一行代码)。现改正如下:

第一步:在canTakePhoto的if语句判断中加入一个判断,从而决定获取Uri对象的转换方式,代码如下:

if(canTakePhoto){    if(Build.VERSION.SDK_INT >= 24){        imageUri = FileProvider.getUriForFile(mContext,                BuildConfig.APPLICATION_ID + ".provider",                mPhotoFile);    }else{        imageUri = Uri.fromFile(mPhotoFile);    }    captureImage.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);}
第二步:在AndroidManifest.xml中对内容提供器进行注册:

其中的provider节点是在application节点下,name属性的值是固定的, authorities属性的值和刚才getUriForFile()方法中的第二个参数一样。内部使用的<meta-data>来指定Uri的共享路径,并引用了一个@xml/file_paths资源。

<provider    android:authorities="${applicationId}.provider"    android:name="android.support.v4.content.FileProvider"    android:exported="false"    android:grantUriPermissions="true">    <meta-data        android:name="android.support.FILE_PROVIDER_PATHS"        android:resource="@xml/file_paths"/></provider>
第三步:创建这个引用的资源。

res/xml/file_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=""/></paths>

经过上述修改之后就能打开相机并进行拍照。


阅读全文
0 0
原创粉丝点击