你或许理解错了Android系统权限管理的这两个概念

作者简介 原创微信公众号郭霖 WeChat ID: guolin_blog

本篇是钊林的第二篇投稿,示例对比了清单权限与运行时权限,并给出了运行时权限的适配方案。希望能够帮助到大家。

钊林的博客地址:

http://teachcourse.cn

正文

摘要

为什么系统禁用录音权限后,在 Android 6.0以上 版本手机运行崩溃?为什么清单文件声明了录音权限,Android 6.0以下 版本仅第一次提示权限授予窗口?为什么使用运行时权限请求,返回权限以授予?怎么让Android应用程序在每次操作时识别系统是否禁用对应权限?如果你和我一样存在很多很多的疑问,说明你还没明白传统的manifest清单文件声明权限和运行时权限请求之间的区别。

对比传统权限声明和运行时权限请求的区别

传统权限声明针对 Android 6.0 及其以下版本使用,Android 6.0对应的API版本23,声明的方式直接将所有应用程序用到的权限统一在 manifest 清单文件中定义,使用标签,应用程序点击安装的过程,罗列清单文件声明的所有权限,安装完成后用户可以选择是否授予应用程序某个隐私的权限,Android系统提供:允许、提示和禁止三种选择,下面看一组演示:

build.gradle 选择编译版本、目标版本都是 API 19,运行在Android 4.4.2系统(华为)效果:


图 1

build.gradle 选择编译版本、目标版本都是 API 19,运行在Android 6.0.1系统(小米)效果


图 2

build.gradle选择编译版本、目标版本都是API 23,运行在Android 4.4.2系统(华为)效果:


图 3

build.gradle选择编译版本、目标版本都是API 23,运行在Android 6.0.1系统(小米)效果:


图 4

图1演示传统权限授予过程,在完成安装的过程中可以选择某个权限是否允许提示禁止状态;

图2演示低版本应用程序在Android 6.0以上系统安装过程,默认授予应用程序清单文件声明的所有权限,小米手机测试无法修改权限状态;

图3图4演示API版本23开发的应用程序分别安装在低版本和高版本系统权限授予过程,安装在低版本时授予权限过程和传统的方式一样,用户可以修改权限的状态;安装到高版本时授予权限过程发生了很大变化,用户安装过程无法修改权限状态,最后运行应用程序的录音功能,出现闪退、崩溃现象。到这里,你是不是和我一样,有一点点明白传统权限声明和运行时权限请求之间的区别吗?

深入理解运行时权限请求过程

是不是我们可以大致认为:使用 API 23 及其以上版本开发的应用程序安装在Android 6.0系统以下的手机,默认授予应用程序清单文件所有的权限,安装在Android 6.0系统以上的手机默认禁止清单文件声明的所有权限?应用程序获取权限的过程中,调用Android开发库提供的一些方法,某个方法返回null或属性为null,就可能导致使用部分功能时应用程序崩溃,而部分被禁止权限的功能虽然不会导致程序崩溃,但也无法获取正确的数值。

运行时权限的出现,一改传统清单文件一键授权的不足,防止用户安装过程的惯性操作,获取了用户某些隐私权限,这些权限包括:收集位置信息读取短信内容记录用户数据等,然后进行一些非法操作:发送短信订阅资费套餐,扣取手机话费等,为了用户隐私信息的安全,API 23开发的应用程序统一在运行时提醒用户授予权限,仅授予针对当前功能使用到的权限,未使用到的权限默认禁止。

那么如何兼容低版本的应用程序呢?以及如何让高版本的应用程序也能在Android 6.0以下系统正常运行?那可能就像文章开头演示的四种效果图。

运行时权限涉及的几个过程:第一检查权限是否被授予,使用方法 checkPermission();第二请求获取权限,使用方法 requestPermissions();第三用户是否授予应用程序权限,监听回调方法 onRequestPermissionsResult(),为了防止应用API 23开发的应用程序在Android 6.0以上系统正常安装,在代码中添加权限检查,如下:

针对图4,运行时请求获取录音权限,然后点击禁止后回调方法 onRequestPermissionsResult(),如下图:


应用程序请求授予权限后,如果用户点击禁止,以后每次权限检查不再出现选择提示窗口,onRequestPermissionsResult() 方法返回权限的状态是 PackageManager.PERMISSION_DENIED,防止反复弹出要求用户授予权限弹窗,如果开发者仍然期待在用户没有禁止权限状态后,再次提醒用户授予权限,需要调用方法 shouldShowRequestPermissionRationale(),该方法的目的显示系统UI说明提示用户重新授予应用程序权限,Nexus 5 测试运行效果,如下:

动图


查看 shouldShowRequestPermissionRationale() 源码说明,详细了解该方法的使用:获取是否你应该通过显示UI说明请求授权的原因,只有当你没有获得该权限,同时当前上下文环境需要的权限没有明确和用户沟通——对于获取该权限有什么用处,这时候你应该调用该方法。比如说,如果你写了一个拍照功能的APP,请求了用户可能需要的拍照权限,而没有解释为什么请求的权限是必须的,可能用户没觉得不正常;然而如果当前APP在拍照时请求获取位置的权限,这时对于一个不精通技术的用户来说可能想知道定位和拍照是怎样的一种联系。在这个情景之下,你大概会选择通过一个显示UI说明请求授权的原因:

说明:Android 6.0.1系统小米手机测试,在用户禁止后,调用 shouldShowRequestPermissionRationale 该方法没有显示说明;使用 Android Studio 内置的Nexus 5模拟器测试用户第一次请求权限弹窗只有 DENY 和 ALLOW 选项,在用户选择 DENY 后再次调用 requestPermissions方法,弹窗除了 DENY 和 ALLOW 选项外,还多了一个 Never ask again 复选框。

关于ActivityCompat的说明

在上面检查授予权限的代码中,我使用了 getPackageManager().checkPermission() 这个方法检查,考虑到兼容高低版本API的问题,还是推荐使用v4包下的 ActivityCompat.checkSelfPermission() 这个静态方法或者父类 ContextCompat.checkSelfPermission();请求权限推荐使用 ActivityCompat.requestPermissions() 这个静态方法,如果第一次禁止后,重新弹窗显示UI说明,调用静态方法 ActivityCompat.shouldShowRequestPermissionRationale() 后重新授权,具体可以查看 ActivityCompat 源码理解它们之间的关系。

在API 23的版本中,查看 ActivityCompat 的源码,上述的三个方法最终来自受保护的类 ActivityCompatApi23,在源码中检查了应用程序的API版本。

响应用户授权状态的回调方法 onRequestPermissionsResult() 属于 ActivityCompat 内部的一个接口,如果没有猜错的话,仅在API 23以后的版本中,实现了 ActivityCompat.OnRequestPermissionsResultCallback接口 的Activity子类,才能回调 onRequestPermissionsResult()方法,同时也会看到 FragmentActivity、AppCompatActivity 源码实现了上述接口。

运行时权限策略

提出了运行时权限,在运行应用程序的时候,每使用应用程序的一个功能开发者就需要请求授权一次,那必然会加大了开发者的工作量,请求权限的代码会变得很多,同时本来运行时权限的申请方式本来就比传统权限请求方式复杂,如果再让开发者一次次请求授权那肯定非常反感。为了解决权限反复多次请求的问题,Google采用了权限分组的策略:同一组的多个权限,只要获得了用户授予的一个权限,同时可以使用同组的其他权限,权限的分组情况如下图:

android.permission-group.CALENDAR

android.permission.READ_CALENDAR

android.permission.WRITE_CALENDAR

android.permission-group.CAMERA

android.permission.CAMERA

android.permission-group.CONTACTS

android.permission.READ_CONTACTS

android.permission.WRITE_CONTACTS

android.permission.GET_GET_ACCOUNTS

android.permission-group.LOCATION

android.permission.ACCESS_COARSE_LOCATION

android.permission.ACCESS_FINE_LOCATION

android.permission-group.MICROPHONE

android.permission.RECORD_AUDIO

android.permission-group.PHONE

android.permission.READ_PHONE_STATE

android.permission.CALL_PHONE

android.permission.READ_CALL_LOG

android.permission.WRITE_CALL_LOG

android.permission.ADD_VOICEMAIL

android.permission.USE_SIP

android.permission.PROCESS_OUTGOING_CALLS

android.permission-group.SENSORS

android.permission.BODY_SENSORS

android.permission-group.SMS

android.permission.SEND_SMS

android.permission.RECEIVE_SMS

android.permission.READ_SMS

android.permission.RECEIVE_WAP_PUSH

android.permission.RECEIVE_MMS

android.permission-group.STORAGE

android.permission.READ_EXTERNAL_STORAGE

android.permission.WRITE_EXTERNAL_STORAGE

参考资料:

https://developer.android.google.cn/guide/topics/security/permissions.html#perm-groups


完。。。。。。。。。。。。。。。。。。。。。

文章原创作者GuoLin 书籍推荐

郭林大神原创android 书籍:《第一行代码 android》

淘宝链接: https://s.click.taobao.com/t?e=m%3D2%26s%3DgKUfuKdAZKocQipKwQzePOeEDrYVVa64K7Vc7tFgwiHjf2vlNIV67p2n%2BQBNMyE6Rku8%2Bpj6eJall3bs%2B3NRhNHnsKI%2BqxhyM0iVZhTFBom4YIorMPnmg8G0g2OJi%2FzmXHfenomYtn5EW9vzeG8LzfPUwktUBEmkxg5p7bh%2BFbQ%3D&pvid=10_106.6.161.154_3367_1490163222155

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容