今日科技快讯

昨日,3.15晚会上曝光了侵害消费者权益的事件:互动百科成最大虚假广告“垃圾站”、郑州科视魔爪伸进几百所学校危害13万孩子眼睛、江苏远方中汇等企业被曝饲料违规使药物添加剂、永旺超市以及无印良品被曝光惊现日本核污染食品、耐克“最好的篮球鞋”气垫消失只有实心橡胶底等。

作者简介

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

钊林 的博客地址:

http://teachcourse.cn

正文

摘要

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

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

传统权限声明针对 Android 6.0 及其以下版本使用,Android 6.0对应的API版本23,声明的方式直接将所有应用程序用到的权限统一在 manifest 清单文件中定义,使用标签 <uses-permission>,应用程序点击安装的过程,罗列清单文件声明的所有权限,安装完成后用户可以选择是否授予应用程序某个隐私的权限,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

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:

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

  1. 对Android系统权限的认识(包含如何获得root权限思路)

    点击打开链接 Android系统是运行在Linux内核上的,Android与Linux分别有自己的一套严格的安全及权限机制, Android系统权限相关的内容, (一)linux文件系统上的权限 -r ...

  2. 系统权限管理设计 (转:http://blog.csdn.net/chexlong/article/details/37697555)

    权限设计(转:http://blog.csdn.net/chexlong/article/details/37697555)      1. 前言:      权限管理往往是一个极其复杂的问题,但也可 ...

  3. Android 系统权限

    Android 是一个权限分隔的操作系统,其中每个应用都有其独特的系统标识(Linux 用户 ID 和组 ID).系统各部分也分隔为不同的标识.Linux 据此将不同的应用之间.应用与系统之间分隔开来 ...

  4. 系统权限管理设计 (转)

    权限设计(初稿)      1. 前言:      权限管理往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断"Who对What(Which)进行How的操作"的逻辑 ...

  5. [Android]之一:Android系统下载管理DownloadManager

    嗷,这个android系统下载管理DownloadManager功能还是蛮强大的.虽然老大只是让我做一个下载工具类给他们使用,但是想加深一下印象,接下来是摘抄笔记,以后也要自己再看看不要又忘了. 一. ...

  6. 系统权限管理功能设计研究

    系统权限管理功能设计研究 一.背景 二.权限级别 三.实现权限管理功能的方法 3.1 数据库表设计 3.1.1 数据库表设计字段 3.1.2 数据库表字段含义 3.2 增删改查封装方法 3.2.1 查 ...

  7. 深入Android系统权限和root权限

    1. Android权限说明 Android系统是运行在Linux内核上的,Android与Linux分别有自己的一套严格的安全及权限机制,Android系统权限相关的内容, (一)linux文件系统 ...

  8. Android系统下载管理DownloadManager

    转载: http://www.trinea.cn/android/android-downloadmanager/ http://www.trinea.cn/android/android-downl ...

  9. android media_rw sdcard_rw,大约Android 了解权限管理

    如Android应用程序开发人员.为android权限机制一直觉得很奇怪.为什么要这个东西权限?为什么要AndroidManifest里面写的uses-permission 这样的事情?我一直搞不清楚 ...

最新文章

  1. 技术16期:如何更好的保证数据质量【大数据篇】
  2. 量子计算生态:市场预期、行业应用与“霸权”争夺
  3. 成功解决 This graphics driver could not find compatible graphics hardware. You maycontinue installation,
  4. DCF模型里面的括号计算方法
  5. 经典文章解释apache与tomcat!看完秒懂
  6. Oracle Length 和 Lengthb 函数说明 .(用来判断记录值里是否有中文内容)
  7. Hadoop之MapReduce程序应用一读取专利引用数据集并对它进行倒排
  8. cookie读取中文时乱码
  9. Duplicate entry ‘XXX‘ for key
  10. Web前端期末大作业--绿色自适应医疗健康医院网页设计(HTML+CSS+JavaScript+)实现
  11. epplus保存为流_C# 使用EPPlus 秒导出10万条数据
  12. 用户无故被扣21000元话费,扣钱容易还钱难,运营商的回应看醉了
  13. mysql前两个月_MySQL数据库表始终保持最近两个月的记录
  14. 东北大学 16春学期《实用写作》在线作业1-3 答案
  15. 智能优化算法(源码)-海鸥优化算法(SOA)
  16. 解决树莓派无法安装QT5 的问题
  17. js实现键盘按键映射
  18. ubuntu18.04中如何设置开机启动脚本,开机启动命令
  19. CentOS防火墙配置(资源)
  20. 1-2 CSS常用样式笔记

热门文章

  1. 饶毅:中国存在大量粗制滥造研究生的问题,很多博士不合格
  2. 摄影技术入门知识及答疑
  3. RNA-seq中的基因表达量计算和表达差异分析
  4. 实战dll注入(原理, 踩坑及排雷)
  5. 100 个网络基础知识看完,可以成半个网络高手
  6. 给事业刚起步者的九个忠告
  7. Android中list常用方法,Android中ListActivity用法实例分析
  8. 逐浪字库新字库出炉!
  9. 【观察】神州数码:向云而生,纵情向前
  10. HTML元素的lang属性的说明及详解