Android动态权限

导语: 随机聊需求中出现几个涉及权限的bug,所以对动态权限机制做了一个简单的整理。

概述

Android应用程序通过请求权限来访问设备数据,例如联系人,短信,SD卡,相机,蓝牙等。应用所需的权限需要在manifest文件中声明,在安装的时候由用户授予。 app安装后就获得了这些权限。运行时不再需要询问用户。

从Android 6.0(Api level 23)开始,引入了动态权限的机制,对权限进行了分类,根据权限的级别,危险权限不再是安装后自动授予,而是需要运行时由用户授予。 这种机制更好的保护了用户的隐私安全,但也给开发人员带来了额外的适配工作,旧版本正常运行的app到6.0以上机器可能会发生crash。

动态权限机制生效需要满足两个条件:

  • manifest 文件中的 targetSdkVersion >= 23
  • 运行的手机系统版本 >= 6.0

权限分类

(1)正常权限:

对用户隐私影响比较小的权限。这些权限在应用安装时授予,运行时不再询问用户。例如: 网络访问、WIFI状态、音量设置等。

(2)危险权限:

涉及用户敏感数据的权限。例如: 读取通讯录、读写存储器数据、获取用户位置等。如果需要使用这些危险权限,首先必须在配置文件中声明,同时在运行时检查是否拥有权限,如果没有需要请求用户授予。

权限组

Android系统对所有权限进行了分组,称为权限组 。属于同一组的危险权限将自动合并授予,用户授予应用某个危险权限,则应用将获得该权限组下的所有权限。

下表为危险权限及其分组:

动态申请权限

1. 检查权限

public int checkSelfPermission(String permission);

检查当前app是否拥有某权限。

  • 有权限: PackageManager.PERMISSION_GRANTED
  • 无权限: PackageManager.PERMISSION_DENIED

当应用需要用到某危险权限时,在执行权限相关代码前,需要使用该方法判断是否已经拥有该权限。有权限继续执行需要权限的代码;无权限则向用户请求授予权限。

2. 申请权限

void requestPermissions (Activity activity, String[] permissions, int requestCode);

当检测到应用没有指定的权限时,调用本方法向用户请求权限。调用此方法将弹出权限请求对话框询问用户 “允许” 或 “拒绝” 指定的权限。

  • 权限参数传入的可以是数组,调用该方法一次请求多个权限;
  • 传入的权限数组参数以单个具体权限为单位,但弹框询问用户授权时,属于同一权限组的权限将自动合并询问授权一次;
  • 请求的权限必须事先在 AndroidManifest.xml 中有声明,否则调用此方法请求时,将不弹框,而是直接返回“拒绝”的结果;
  • 第一次请求权限时,用户点击了“拒绝”,第二次再请求该权限时,对话框将出现“不再询问”复选框,如果用户勾选了“不再询问”并点击了“拒绝”,则之后再请求此权限组时将不弹框,而是直接返回“拒绝”的结果。

3. 处理权限请求的响应

调用requestPermissions请求权限后,在下面的回调中获取用户的选择结果。

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);

  • requestCode请求权限时传入的请求码,用于区别是哪一次请求的
  • permissions 所请求的所有权限的数组
  • grantResults 权限授予结果,和 permissions 数组参数中的权限对应, 值有两种:
    1. 授予: PackageManager.PERMISSION_GRANTED
    2. 拒绝: PackageManager.PERMISSION_DENIED

4. 提示用户授予权限的理由

boolean shouldShowRequestPermissionRationale (Activity activity, String permission)

判断是否有必要向用户解释为什么要这项权限。如果应用第一次请求过此权限,但是被用户拒绝了,则之后调用该方法将返回 true,此时就有必要向用户详细说明需要此权限的原因。

  • 如果应用第一次请求此权限时被用户拒绝,第二次再请求此权限时,用户勾选了权限请求对话框的“不再询问”,则此方法返回 false。
  • 如果设备规范禁止应用拥有该权限,此方法也返回 false。

版本兼容

由于以上几个方法都是在 Api level 23中才引入,如果需要运行在低版本中,需要做版本兼容。 support 包中有对应的兼容方法:

ContextCompat.checkSelfPermission() ActivityCompat.requestPermissions() ActivityCompat.shouldShowRequestPermissionRationale()

例子

这几个方法的使用比较简单,例子略,现在手Q android版的 targetSdkVersion=”9” 暂时还不涉及适配的工作。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Timhbw博客

分享下平时我在windows平台下开发用的一些比较好的软件-Notepad++(二)

2016-03-0923:23:39 发表评论 947℃热度 Notepad++ 它是 Windows操作系统下的一套文本编辑器(软件版权许可证: GPL),...

29513
来自专栏圣杰的专栏

ABP入门系列(9)——权限管理

源码路径:Github-LearningMpaAbp 完成了简单的增删改查和分页功能,是不是觉得少了点什么? 是的,少了权限管理。既然涉及到了权限,那我们...

3945
来自专栏零基础使用Django2.0.1打造在线教育网站

利用Flask搭建微电影视频网站(五):访问控制器

努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

702
来自专栏智能算法

Jupyter notebook使用指南

一、Jupyter介绍 Jupyter Notebook是以web交互式的编程接口,是IPython notebook的升级版本。主要是针对python,另外...

8188
来自专栏IMWeb前端团队

FIS源码-fisrelease概览

本文作者:IMWeb 陈映平 原文出处:IMWeb社区 未经同意,禁止转载 前面已经已fis server open为例,讲解了FIS的整体架构设计,...

1928
来自专栏Golang语言社区

Go微服务 - 构建我们的第一个服务

虽然通过HTTP提供JSON服务不是内部服务和外部服务的唯一选择,但本文聚焦的是HTTP和JSON. 使用RPC机制和二进制消息格式(例如Protocol Bu...

1224
来自专栏FreeBuf

一次与缓冲区溢出的亲密接触

这是一个简单的缓冲区溢出的漏洞,今天没事,来分析一下看看他溢出的原因,最后通过平衡堆栈的方式,让目标程序执行shellcode使程序不crash。只是用来研究和...

1120
来自专栏JackieZheng

Nodejs学习笔记(四)——支持Mongodb

前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs...

1785
来自专栏Vamei实验室

被解放的姜戈06 假作真时

之前了解了: 创建Django项目 数据库 模板 表格提交 admin管理页面 上面的功能模块允许我们做出一个具有互动性的站点,但无法验证用户的身份。我们这次了...

1876
来自专栏24K纯开源

macOS下利用dSYM文件将crash文件中的内存地址转换为可读符号

一、使用流程     Windows下的程序运行崩溃时,往往可以利用pdb文件快速解析出程序崩溃的具体位置,甚至可以对应到源代码的具体行数。macOS下的sym...

17510

扫码关注云+社区