热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

设备管理器添加androidphone_重新梳理Android权限管理

文章首发在个人公众号:追风记忆,公众号微信号:zhuifengThreadAndroidDeveloper指南中,对Andr

文章首发在个人公众号:追风记忆,公众号微信号:zhuifengThread

Android Developer指南中,对Android安全体系结构的核心有这么一个说法:默认情况下,任何应用程序都无权执行任何会对其他应用程序、操作系统或者用户产生负面影响的操作。这句话其实就很好的诠释了权限管理的意义,即用户才是手中设备的主人,没有用户的允许,设备不可以私自记录用户的通讯录,不可以上传用户的姓名和身份证号,更不可以偷偷地窃取属于用户的高级隐私。但在如今的手机程序中,特别是一些流氓应用,私自获取用户高级权限的现象也不少见。随着Android版本的更新,对于权限这一块也比以往做得更好了。这一次重新梳理权限管理环节,并通过实例展示在Android 6.0版本后的权限处理过程。所以篇幅较长,字,阅读大概需要**分钟。

什么是Android权限?

权限(Permission),顾名思义是一种对信息访问的申请。Android的权限有上百种,例如应用程序尝试调用拨号权限、调用摄像头权限、调用读取短信权限、调用读取通讯录权限等等。对于这些权限,Android将其按照危险等级进行了划分分组,分成如下的三种类别:

  1. 正常权限(PROTECTION_NORMAL):指的是应用程序需要访问的一些数据资源,但并不涉及到用户的隐私或者对其他应用程序无害。例如设置闹钟就是属于正常权限。Android在处理正常权限时并不会提示用户,而用户也没有办法取消这些正常权限
  2. 签名权限(PROTECTION_SIGNATURE):指的是Android在安装时授予应用程序的权限,利用签名权限,两个签名相同的应用程序就可以进行安全的数据共享。
  3. 危险权限(PROTECTION_DANGEROUS ):指的是直接触碰到用户隐私或者影响其他程序操作的权限,对于这一类的权限,Android会以弹窗的方式向用户进行问询,应用程序必须要经过用户的授权后才可以进行相应的行为

以危险权限为例,Android规定了如下的权限必须请求用户的许可。

905bfe94b5aabc2010c0b279ed0dbad8.png

Android危险权限组和部分权限示例

Android权限获取的方式

对于程序中申请的权限,都应该在AndroidManifest.XML文件中进行注册,否则申请的权限将无法发挥作用。下图中的AndroidManifest文件中添加了打电话和摄像头的权限。

5d265062bc72b2f930c6528fadd1c83b.png

注册权限

Android权限获取可以分成两个阶段,在Android 6.0之前,所申请的权限只要在AndroidManifest文件中列举就可以了,并会在程序安装时全部显示在安装页面上,这个过程并不区分权限是否为常规权限还是正常权限。这种方式是造成早期Android系统在隐私性做的不好的直接原因,因为用户在安装应用程序时,很多时候并不会去仔细查看程序弹出的方框到底包含了哪些危险的权限,为了尽快的进入程序首页,一般都会同意全部弹出的权限,这就给了很多流氓程序肆意发挥的入口。下图展示了Android 5.0安装界面的部分危险权限截图。

c1fc77a7f8d42d94772dbad6d2b2a68b.png

Android 5.0 安装界面

Google显然也注意到了这一点,于是在Android 6.0中推出了一种运行时权限管理机制,这种机制对原有的权限处理方式进行了很大程度的改善:应用程序安装后,点开程序时,不再是列出程序申请的所有权限,而是将部分危险权限与应用本身的功能相关联。例如相机应用,只有当用户点击拍照按钮时,系统就会弹出申请摄像头的权限,这种方式将用户的注意力集中到了当下的操作上,使得用户有足够的时间和意愿去判定是否同意程序的权限申请,并且用户随时可以在设置中关掉授予程序的危险权限,从而极大程度上避免了对危险权限的放行,保护了用户的隐私。

Android 6.0之后的运行时权限处理机制很好的解决了危险权限的获取问题,它具有如下的两个行为:

  • 如果应用程序在当前的权限组(一组权限的集合)中没有任何权限,那么在请求权限时,系统会显示该权限组的请求对话框,例如程序请求CALL_PHONE权限,那么Android将弹出CALL权限对话框显示应用希望拨打电话功能。
  • 如果一个权限组中的任意一个权限被授权,那么该权限组中的其他权限都会被Android默认授权。例如上面的CALL_PHONE权限被允许,那么PHONE权限组中的其它权限,例如READ_PHONE_NUMBERS读取电话号码的权限就会默认被授权,并且不会向用户弹框显示权限申请过程。

运行时权限处理机制中的第二点的特性并不被Google推崇,Google认为后续的Android版本中这个特征可能会发生变化,并建议开发者应明确指出所需要的每一个权限。

Android实现权限管理

关于Android权限更详细的介绍可以在官方的Android Developer指南中查阅。重点是如何在实践中学会使用Android权限,后半部分将会以代码和流程图的方式展示Android权限管理。

Android权限处理可以分解为三个部分:

  1. 检查权限:权限是否为危险权限,正常权限会被系统默认允许,危险权限需要用户手动允许,所以我们的权限讨论范围是危险权限的获取,在Android中检查权限是否获取的方法是ContextCompat.checkSelfPermission(),这个方法返回一个int类型的PERMISSION_GRANTED或者PERMISSION_DENIED,一般来说,程序刚申请权限的时候都是处于PERMISSION_DENIED状态,因此需要后续的申请过程。
  2. 请求权限:当权限并没有被允许的情况下,就需要向用户请求处理权限申请,在应用层上则表现为Android系统会弹出一个对话框,提示用户进行操作。
  3. 从代码层面考虑,Android提供了一个requestPermissions()的调用方法来请求相应权限,这个方法接受目标Activity、需要请求授权的权限组和识别权限请求的请求代码作为参数传递,并且它是一个异步的方法,并返回产生的结果。
  4. 处理权限响应:当用户对弹出的权限申请框进行响应后,Android会调用onRequestPermissionsResult()方法,将用户的响应作为参数传递。开发者必须使用@Override声明覆盖这个方法,来确认这个权限是否真的被用户所允许,并进行后续的业务逻辑编写。
6b7213fc3fdcaa34aaaccd05b110a407.png

Android 6.0权限管理

权限获取的一般过程就是遵循上面的三个步骤进行的,但是千万不要忘记了所申请的权限一定要在AndroidManifest.xml中注册,不然就准备尝尝异常抛出铁拳的力量吧。

当然,更清晰明了的是用流程图来展示权限申请和授权的过程。

1b6622560cd8820ef86b3657a75cfd3c.png
单个权限的获取过程

下面以获取打电话的权限为例,通过代码实现的方式来解释这个流程的具体做法。以下面一个Demo的页面为测试对象,只要点击获取电话权限按钮,就会弹出权限提示窗,然后允许该请求,就可以实现跳转到拨号页面进行通话的功能。

cfb4ead7b0f94b1068e8b1d26002b468.png

页面Demo

第一部分是检测权限部分。点击获取电话权限按钮,就会调用程序中的callPermission()这个方法,在callPermission中调用checkSelfPermission的方法进行权限检测,实参是当前的Activity对象和对应的权限,这个方法返回一个int类型的值,其中若权限允许则返回值为0的PERMISSION_GRANTED,否则返回值为-1的PERMISSION_DENIED,当权限已经被允许的情况下,直接调用else语句中的callPhone()方法,意味着直接可以拨打电话了。

当权限检测为未允许的情况下,进入请求权限状态,即if语句中的requestPermissions这个方法,这个方法会创建一个字符串数组,将请求的权限同一放入这个数组中,最后一个参数是一个int类型的requestCode,该值在后续的处理权限中发挥作用,并且这个值不一定取1,只要这个值大于等于0即可。为了方便起见,这里取1作为请求码。

@Override public void onClick(View view) { switch (view.getId()){ case R.id.getCallPermission: Toast.makeText(MainActivity.this, "获取打电话权限



推荐阅读
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
author-avatar
Andiry舍甫琴科
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有