在 Android 7.0 之前 Google 提供的动态申请权限的 API, 可以调用相机拍照, 访问 SDcard 等操作都只需要申请对应的权限, 如下:
- <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 中进行注册的, 注册方法如下:
- <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. 获取相机权限
- /**
- * 自动获取相机权限
- */
- 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 { // 有权限直接调用系统相机拍照
- }
- }
参考: https://www.jianshu.com/p/12b8812038d8
来源: http://www.bubuko.com/infodetail-3086995.html