Android 7.0 之后相机/文件读写等权限获取方式改变,导致开启相机闪退

在 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

原文地址:https://www.cnblogs.com/ichenwin/p/10992380.html

时间: 2024-10-11 06:29:11

Android 7.0 之后相机/文件读写等权限获取方式改变,导致开启相机闪退的相关文章

Android 5.0 system_fonts.xml文件的解析过程

Android 5.0 system_fonts.xml文件的解析过程 首先看看看5.0 中familyset version="22" 的格式 20 <family name="sans-serif"> 21 <font weight="100" style="normal">Roboto-Thin.ttf</font> 22 <font weight="100"

Android编程入门--android 7.0 的so文件

参考博客:android 7.0对开发者会有哪些影响 参考博客:android 7.0 因为.so文件而崩溃事件解决 由于调用系统so出错 将系统so拷贝出来使用即可.

.net学习笔记--文件读写的几种方式

在.net中有很多有用的类库来读写硬盘上的文件 一般比较常用的有: File:1.什么时候使用:当读写件大小不大,同时可以一次性进行读写操作的时候使用         2.不同的方式可以读写文件类型不一样. ReadAllBytes()  WriteAllByte():可以读写任意类型的文件 (里面封装的是FileStream)           ReadAllLines()  ReadAllText():(里面封装是StreamWriter,StreamReader),只能读写文本类型文件

Linux文件读写机制及优化方式

导读 Linux是一个可控性强的,安全高效的操作系统.本文只讨论Linux下文件的读写机制,不涉及不同读取方式如read,fread,cin等的对比,这些读取方式本质上都是调用系统api read,只是做了不同封装.以下所有测试均使用open, read, write这一套系统api. 缓存 缓存是用来减少高速设备访问低速设备所需平均时间的组件,文件读写涉及到计算机内存和磁盘,内存操作速度远远大于磁盘,如果每次调用read,write都去直接操作磁盘,一方面速度会被限制,一方面也会降低磁盘使用寿

linux下查看修改文件读写执行权限

查看文件权限的语句: 在终端输入:ls -l xxx.xxx (xxx.xxx是文件名) 那么就会出现相类似的信息,主要都是这些:-rw-rw-r-- 一共有10位数 其中: 最前面那个 - 代表的是类型 中间那三个 rw- 代表的是所有者(user) 然后那三个 rw- 代表的是组群(group) 最后那三个 r-- 代表的是其他人(other) 然后我再解释一下后面那9位数: r 表示文件可以被读(read) w 表示文件可以被写(write) x 表示文件可以被执行(如果它是程序的话) -

##从0开始写一个混合app(andriod)##第3天,解决白屏闪退问题

2017年4月1日20:28:01 焦灼,无奈,丝毫没有头绪,好好的,怎么就闪退了呢? 看了下官方的qa,说是悬浮框权限没有打开会有这种情况. 后面附带的是MIUI的解决方案.我的手机是联想zuk,自己找了一下 设置>权限管理>按应用管理>myapp >打开悬浮框权限 接下来重新尝试react-native run-android,终于手机上弹出了 welcome to react-native 的欢迎界面 这里的提示是让我们修改 index.android.js文件就可以修改这个

android app调试没问题,但打包签名的apk,运行时出现闪退怎么办?

在用Eclipse编写Android app时,有时调试时没有问题,但一经打包签名,运行就出现闪退,还报错说找不到某某类.一开始以为是混淆导致的,后来我没有混淆竟然也还是这个问题.无奈只得网上寻找解决方案,最终还是有人解决了的,方法也很简单,只需按照下面几步来就可以了: 1.找到Project -> Build Automatically,取消它关闭自动编译2.然后Clean一下3.最后在手动Build一下 然后你再打包签名,这样就可以正常运行了.

android小功能实现之文件读写

新建一个Android工程. 一 布局 先看效果图: 打开main.xml修改内容如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_wid

Android SD卡简单的文件读写操作

首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: <!-- SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 向SDCard写入数据权限 --> <uses-permission android:name="