在 Android 7.0 以前 Google 提供的动态申请权限的 API,能够调用相机拍照,访问SDcard等操做都只须要申请对应的权限,以下:java
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
可是 7.0 更新以后,Google 收紧了对私有目录的访问权限 。Android 7.0 中尝试传递 file://URI 会触发 FileUriExposedException,由于在 Android 7.0 以后 Google 认为直接使用本地的根目录即 file://URI 是不安全的操做,直接访问会抛出 FileUriExposedExCeption 异常,这就意味着在Android 7.0 之前咱们访问相机拍照存储时,若是使用URI的方式直接存储剪裁图片就会形成这个异常,那么如何解决这个问题呢?
Google 为咱们提供了 FileProvider 类,进行一种特殊的内容提供,FileProvider 是 ContentProvide 的子类,它使用了和内容提供器相似的机制来对数据进行保护,能够选择性地将封装过的 URI 共享给外部,从而提升了应用的安全性。下面就让咱们看一下如何使用这个内容提供者进行数据访问的:
1. 使用 FileProvider 获取 URI 就会将之前的 file://URI 准换成 content://URI,实现一种安全的应用间数据访问,内容提供者做为 Android 的四大组件之一,使用一样须要在清单文件 AndroidManifest.xml 中进行注册的,注册方法以下:android
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.cc.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
2. 在res目录下建立 xml 文件夹,file_paths.xml 文件内容以下:安全
<?xml version="1.0" encoding="utf-8"?> <paths> <external-path name="camera_rec" path="" /> </paths>
3. 获取相机权限ide
/** * 自动获取相机权限 */ private void autoObtainCameraPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, CAMERA_PERMISSIONS_REQUEST_CODE); } else { //有权限直接调用系统相机拍照 } }