博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android6 0新应用权限管理机制详解
阅读量:6420 次
发布时间:2019-06-23

本文共 4031 字,大约阅读时间需要 13 分钟。

随着Android系统的不断升级,Android系统在系统安全这一块也有了一定的提升,比如在Android5.0之前,用户安装任何应用都必须无条件接受该应用在AndroidManifest.xml文件中声明的权限,否则就只能不安装此应用,这也给了一些别有用心的应用可乘之机,用户的隐私也没法得到保证。到了Android5.0开始,用户在安装应用时会出现一个复选框,让用户选择授予该应用的一些权限,不选择则该应用不会拥有该权限。进入Android6.0以后,Google进一步对权限进行了控制,对于一些危险权限,必须在使用时动态申请,由用户授权之后,应用才会拥有该权限,这更加加强了应用的安全性。但这个变化也使得我们以前可以正常运行的应用受到了一定的影响,我们必须对其做一定的适配才能保证我们的应用正常运行,下面我们就来一起学习一下Android6.0的权限管理机制。

一、正常权限和危险权限

下面是Android官网对正常权限危险权限的解释:

  • 正常权限涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。例如,设置时区的权限就是正常权限。如果应用声明其需要正常权限,系统会自动向应用授予该权限。
  • 危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如,能够读取用户的联系人属于危险权限。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限。

除了上面说的正常权限和危险权限,还有一个权限组的概念需要了解,权限组简单点理解就是讲权限进行分组,比如READ_CALENDAR权限和WRITE_CALENDAR权限属于CALENDAR这个组。任何权限都可属于一个权限组,包括正常权限和应用定义的权限。但权限组仅当权限危险时才影响用户体验。可以忽略正常权限的权限组,所以可以说所有危险的 Android 系统权限都属于权限组。

下面列出危险权限及其所属的组:

权限组 权限
CALENDAR READ_CALENDAR
WRITE_CALENDAR
CAMERA CAMERA
CONTACTS READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE RECORD_AUDIO
PHONE READ_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

除了上面的表,我们还可以在命令行中查看危险权限及其所属的组,在命令行中输入以下内容即可得到结果:

adb shell pm list permissions -g -d复制代码

二、应用请求危险权限的处理

下面我们说说应用在请求危险权限时系统的处理,如果设备运行的是 Android 6.0(API 级别 23),并且应用的 targetSdkVersion 是 23 或更高版本,则当用户请求危险权限时系统会发生以下行为:

  • 如果应用请求其清单中列出的危险权限,而应用目前在权限组中没有任何权限,则系统会向用户显示一个对话框,描述应用要访问的权限组。对话框不描述该组内的具体权限。例如,如果应用请求 READ_CONTACTS 权限,系统对话框只说明该应用需要访问设备的联系信息。如果用户批准,系统将向应用授予其请求的权限。
  • 如果应用请求其清单中列出的危险权限,而应用在同一权限组中已有另一项危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。例如,如果某应用已经请求并且被授予了 READ_CONTACTS 权限,然后它又请求 WRITE_CONTACTS,系统将立即授予该权限。

上面是Android官网的介绍,从中可以看到很重要的一点 系统只告诉用户应用需要的权限组,而不告知具体权限

三、代码实战权限管理机制

上面说了那么多理论,现在就开始真正的实战,其实就简单的下面几步即可完成,我们下面以申请打电话权限为例:

1 . 在AndroidManifest.xml文件中添加需要的权限(适配Android6.0以下的系统)

AndroidManifest.xml文件中添加如下权限

复制代码

2 . 检查危险权限

我们在开始打电话之前必须先要检查我们是否拥有打电话的权限,对于正常的权限,系统默认是授予的,但对于打电话这种危险权限我们就必须先进行检查,此处调用ContextCompat.checkSelfPermission()方法进行检查,如果检查的结果是用户已经授予了我们此权限,那我们就可以直接调用打电话的逻辑,如果没有,那我们必须进行权限申请。

if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)        != PackageManager.PERMISSION_GRANTED){    //做权限申请处理    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQUEST_CODE);}else{    //用户已经授权,直接处理业务逻辑打电话    doCallPhone();}复制代码

3 . 申请授权

可以看出我们上面使用ActivityCompat.requestPermissions()方法申请权限,此方法的第二个参数可以传入一个权限数组,我们可以一次性申请多个权限,第三个参数是一个请求码,用于我们在下一步中根据申请的结果做回调处理。

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQUEST_CODE);复制代码

4 . 处理申请回调

我们通过重写onRequestPermissionsResult()方法来处理回调结果

@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {    switch (requestCode){        case CALL_PHONE_REQUEST_CODE:            //打电话权限回调处理            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){                //打电话权限被授予                doCallPhone();            }else {                //本次拒绝了权限请求,提示用户权限未被授予                Toast.makeText(this, "权限申请失败", Toast.LENGTH_SHORT).show();            }            break;        default:            break;    }}复制代码

上面的requestCode就是我们在申请权限时提供的请求码,grantResults中存放着我们每个权限所对应的申请结果,由于我们只申请了一个权限,所以grantResults[0]即可。

当然,如果你向用户申请一个权限,而用户又拒绝了你的权限,等下次用户申请的时候还是会弹出用户授权窗口,这个时候你或许想更加清楚地给用户解释一下你为什么使用该权限,这个时候就需要用到ActivityCompat.shouldShowRequestPermissionRationale()这个方法。

这个方法会在应用首次安装时返回false,当用户拒绝了一次你的权限后也会返回true

注:当用户点击了授权窗口上的不再询问复选框时,该方法会返回false,你可以根据用户的行为来做出一些反应,但一般的权限申请窗口都对所申请的权限有一定的说明,除非特别情况,我们没有必要自己进行权限的说明解释。

四、更加优雅的实现权限申请及管理

说了上面那么多,你会发现权限申请最主要的就那么几步,但我们不能总是在每次需要申请的时候重复写代码,这个时候我们就可以去看看别人封装的库,其实也可以自己进行封装,下面推荐两个PermissionGenMPermissions

  • PermissionGen是一个韩国人封装的,项目链接在此 : https://github.com/lovedise/PermissionGen
  • MPermissions是鸿神封装的库,项目链接在此 : https://github.com/hongyangAndroid/MPermissions

上面的两个库都有详细的使用方法,这里不再赘述,第一个库是基于运行时注解,使用时会影响性能,第二个库是基于编译时注解,对性能不会有影响。

转载地址:http://mtlra.baihongyu.com/

你可能感兴趣的文章
DIV+CSS命名规范有助于SEO
查看>>
js生成二维码
查看>>
C指针练习
查看>>
web项目buildPath与lib的区别
查看>>
php对redis的set(集合)操作
查看>>
我的友情链接
查看>>
ifconfig:command not found的解决方法
查看>>
计算机是怎么存储数字的
查看>>
Codeforces Round #369 (Div. 2) A. Bus to Udayland 水题
查看>>
adb上使用cp/mv命令的替代方法(failed on '***' - Cross-device link解决方法)
查看>>
C++标准库简介、与STL的关系。
查看>>
Spring Boot 3 Hibernate
查看>>
查询EBS请求日志的位置和名称
查看>>
大型机、小型机、x86服务器的区别
查看>>
J2EE十三个规范小结
查看>>
算法(第四版)C#题解——2.1
查看>>
网关支付、银联代扣通道、快捷支付、银行卡支付分别是怎么样进行支付的?...
查看>>
大数据开发实战:Stream SQL实时开发一
查看>>
C++返回引用的函数例程
查看>>
dll 问题 (转)
查看>>