为什么有权限机制

我们知道 Android 应用程序是沙箱隔离的,每个应用都有一个只有自己具有读写权限的专用数据目录。但是如果应用要访问别人的组件或者一些设备上全局可访问的资源,这时候权限机制就能系统化地规范并强制各类应用程序的行为准则。

权限的本质

在 Android 中,一个权限,本质上是一个字符串,一个可以表示执行特定操作的能力的字符串。比如说:访问 SD 卡的能力,访问通讯录的能力,启动或访问一个第三方应用中的组件的能力。 权限被授予了之后,首先会在内存和本地中有记录,这在调用系统binder服务和其他应用组件时做鉴权依据,比如调用系统binder服务时会通过Binder.getCallingUid()拿到调用者的Uid,而Uid一般都是与应用包名一一对应的,再拿这个Uid到PMS里去查这个应用对应的权限。 其次会按被授予的权限将应用分到某个组。 可以参考https://www.jianshu.com/p/a17c8bed79d9

自定义权限

image.png

pm list permissions -f 命令可以详细查看 Android 所有预定义的权限。

可以看到一个权限的信息包括:定义的包名、标签、描述、权限组和保护级别。

权限组

权限根据设备的功能或特性分为多个组。如果应用已在相同权限组中被授予另一危险权限,系统将立即授予该权限,如READ_CONTACTS和WRITE_CONTACTS。

权限的级别

normal 级别 权限保护级别的默认值,无须用户确认,只要声明了,就自动默默授权。如:ACCESS_NETWORK_STATE。

dangerous 级别 赋予权限前,会弹出对话框,显式请求权限。如:READ_SMS。因为 Android 需要在安装时赋予权限,所以安装的确认对话框,也会显示列出权限清单。

signature 级别 signature 级别的权限是最严格的权限,只会赋予与声明权限使用相同证书的应用程序。 以系统内置 signature 级别权限为例,Android 系统应用的签名由平台密钥签发,默认情况下源码树里有 4 个不同的密钥文件:platform、shared、media 和 testkey。所有核心平台的包(如:设置、电话、蓝牙)均使用 platform 密钥签发;搜索和通讯录相关的包使用 shared 签发;图库和媒体相关的包使用 media 密钥签发;其他的应用使用 testkey 签发。定义系统内置权限的 framework-res.apk 文件是使用平台密钥签发的,因此任何试图请求 signature 级别内置权限的应用程序,需要使用与框架资源包相同的密钥进行签名。

signatureOrSystem 级别 可以看做是一种折中的级别,可被赋予与声明权限具有相同签名证书密钥的应用程序(同 signature 级别)或者系统镜像的部分应用,也就是说这允许厂商无须共享签名密钥。Android 4.3 之前,安装在 system 分区下的应用会被自动赋予该保护级别的权限,而 Android 4.4 之后,只允许安装在 system/priv-app 目录下的应用才能被主动赋予。

特殊权限

SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS由于其特殊性,其申请方式与其它权限都不同。

/**

* 申请权限

*/

private void requestWriteSettings()

{

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)

{

//大于等于23 请求权限

if ( !Settings.canDrawOverlays(getApplicationContext()))

{

Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);

intent.setData(Uri.parse("package:" + getPackageName()));

startActivityForResult(intent, REQUEST_CODE_OVERLAY );

}

}else{

//小于23直接设置

}

}

其授予流程如下:

起了com.android.settings下一个叫Settings$OverlaySettingsActivity的Activity,并把需要授权应用的包名带了过去。

通过AppOpsManager给指定的包名授予权限。

image.png

普通运行时权限的请求授予流程

image.png

//检测是否有写的权限

int permission = ActivityCompat.checkSelfPermission(this,

"android.permission.WRITE_EXTERNAL_STORAGE");

if (permission != PackageManager.PERMISSION_GRANTED) {

// 没有写的权限,去申请写的权限,会弹出对话框

ActivityCompat.requestPermissions(this,

new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

}

} catch (Exception e) {

e.printStackTrace();

}

这里简要分析下ActivityCompat#requestPermissions的流程:

判断android版本是否小于6.0,若小于,让PMS查询一把自己是否有声明这个权限;若大于6.0,则启动了com.android.packageinstaller/.permission.ui.GrantPermissionsActivity这个具有悬浮窗样式的Activity。

在GrantPermissionsActivity中做了权限变更的操作后,最终还是调用到PMS去做实质上的更新操作,com.android.server.pm.permission.PermissionManagerService#grantRuntimePermission。

查询该权限是否在manifest文件中有声明。

做授权操作,更新内存中的权限信息。

将权限信息持久化到本地文件/data/system/users/0/runtime-permissions.xml中,以便重启时可以恢复权限信息。

不同权限的授予方式

普通权限: 清单文件中声明即可。

危险权限: 方式一: pm grant application_package android.permission.CHANGE_CONFIGURATION 方式二:appops set application_package permission_num 0/1

权限的发展

android 4.4 访问sd卡需要申请权限。 您的应用在 Android 4.4 上运行时无法读取外部存储空间上的共享文件,除非您的应用具有 READ_EXTERNAL_STORAGE权限。也就是说,没有此权限,您无法再访问 getExternalStoragePublicDirectory()返回的目录中的文件。但是,如果您仅需要访问 getExternalFilesDir() 提供的您的应用特有目录,那么,您不需要 READ_EXTERNAL_STORAGE`权限。

android 6.0 运行时权限。 此版本引入了一种新的权限模式,如今,用户可直接在运行时管理应用权限。这种模式让用户能够更好地了解和控制权限,同时为应用开发者精简了安装和自动更新过程。用户可为所安装的各个应用分别授予或撤销权限。 对于以 Android 6.0(API 级别 23)或更高版本为目标平台的应用,请务必在运行时检查和请求权限。要确定您的应用是否已被授予权限,请调用新增的 checkSelfPermission()方法。要请求权限,请调用新增的 requestPermissions()方法。即使您的应用并不以 Android 6.0(API 级别 23)为目标平台,您也应该在新权限模式下测试您的应用。 如需了解有关在您的应用中支持新权限模式的详情,请参阅使用系统权限。如需了解有关如何评估新模式对应用的影响的提示,请参阅权限最佳做法。

android 7.+ 应用间共享文件要使用FileProvider。 对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file://URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。 要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider`类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。

android 8.+

同一权限组的权限在被授予了之后也需要显式的再申请一次。

在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。 对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。 例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE。应用请求 READ_EXTERNAL_STORAGE,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE,则系统会立即授予该权限,而不会提示用户。

android 9

隐私权限变更。

为了增强用户隐私,Android 9 引入了若干行为变更,如限制后台应用访问设备传感器、限制通过 Wi-Fi 扫描检索到的信息,以及与通话、手机状态和 Wi-Fi 扫描相关的新权限规则和权限组。

android 10

隐私权变更。

外部存储访问权限范围限定为应用文件和媒体,在后台运行时访问设备位置信息需要权限,针对从后台启动 Activity 的限制等。

Android pms权限管理,Android权限机制相关推荐

  1. 用户权限管理之权限管理

    文章目录 1 基本权限 2 权限管理 3 权限掩码 umask 4 特殊权限 5 特殊属性 1 基本权限 权限 对应数字 意义 r(readable) 4 可读 w(writable) 2 可写 x( ...

  2. python用户权限管理_python---RBAC权限管理项目

    设计标准一  **** 项目需求描述:这是一个真实的项目后端管理平台       要实现如下的功能: 1.在管理页面输入用户名密码,可以登陆到主页 2.不同角色的用户显示的菜单个数不同 3.同一角色用 ...

  3. JAVAWEB开发之权限管理(一)——权限管理详解(权限管理原理以及方案)、不使用权限框架的原始授权方式详解

    知识清单 1.了解基于资源的权限管理方式 2. 掌握权限数据模型 3. 掌握基于url的权限管理(不使用Shiro权限框架的情况下实现权限管理) 4. shiro实现用户认证 5. shiro实现用户 ...

  4. android 获取权限管理,Android常用权限获取和设置

    Android常用权限获取和设置 1 活动管理器 权限 代码 ActivityManager activityManager = (ActivityManager) getSystemService( ...

  5. 原生android 权限管理,Android 权限管理(原生、EasyPermissions、RxPermissions)

    前言:动态权限管理是Android6.0(Build.VERSION_CODES.M = Api23)推出的,提醒用户当前APP所需要的权限,防止滥用.这些权限一般分为三种:(1)普通权限:直接man ...

  6. android 加网络权限管理,Android添加用户组及自定义App权限的方法

    Android:4.4.4 一.应用场景 在Android设备上,现在我们外接了一个USB转串口的设备,设备节点是/dev/ttyUSB0: # ls -l /dev/ttyUSB0 crw-rw-- ...

  7. android superuser.apk 管理root权限原理分析

    原文出处:http://blog.163.com/szs121@126/blog/static/109056781201223111390835/ 使用android 手机很多情况下需要root权限, ...

  8. 麦克风android权限管理,android权限处理详解

    写在前面 对于android 6.0来说,增加了权限的管理,能够更好的保护用户的隐私,当用户需要某权限时,才动态的去申请.用户也可以在应用权限管理里面关闭和打开.为了方便以后使用,这里对权限使用相关做 ...

  9. android 华为开发权限管理,android开发 华为 点击跳转到权限管理页面

    private void goHuaWeiSetting()  { try { //HUAWEI H60-l02 P8max测试通过 Log.d(MainActivity.class.getSimpl ...

最新文章

  1. AS3中的序列化与反序列化
  2. 用真实脑电波提高魔法伤害!硬核玩家改造《上古卷轴V》,脑机接口控制魔法施放...
  3. selenium元素的定位以及操作 第二章
  4. 弹出框页面中使用jquery.validate验证控件
  5. sourcetree,创建工作流报错:Fatal: Not a gitflow-enabled repo yet. Please run 'git flow init' first.-》解决办法...
  6. 消息分发的同步均衡策略
  7. Hollowjars,部署扫描程序以及Wildfly群体为何很棒
  8. 节省服务器成本50%以上!独角兽完美日记电商系统容器化改造实践
  9. 蚕豆有什么营养价值?
  10. tfs 文件系统部署_使用SQL Server数据工具和使用自定义工作流文件的TFS部署到多个数据库
  11. java字符相似_JAVA 获取两个字符串的相似度
  12. easyUI 动态参数名称和动态参数值
  13. python中使用连续关系运算符_解释一下Python中的关系运算符
  14. Ubuntu 下用 enca 转化文件字符编码
  15. 云打印SDK来袭,支持飞鹅云,芯烨云,易联云,优声云等云打印机
  16. MQ系列SpringBoot快速整合RabbitMQ
  17. Unable to read entire header; 80 bytes read; expected 512 bytes
  18. 二手苹果手机价格查询
  19. 如何解决python中文问题_布同:如何解决Python中文问题(总结了多位前人经验,初学者必看)...
  20. python any函数_python中的any函数是什么?如何使用any函数?

热门文章

  1. Spring MVC-ContextLoaderListener和DispatcherServlet
  2. linux实践-弱密码导致服务器被黑
  3. android屏幕分辨率详解 ldpi mdpi hdpi 程序UI自适应 《官方翻译》
  4. 如何在Windows Server 2008 Core里面添加Role~~~
  5. windows 2008 (非R2)使用批处理文件调整组策略过程记录
  6. 区块链编程完全指南:平台、语言与结论
  7. c语言中浮点数和整数转换_C中的数据类型-整数,浮点数和空隙说明
  8. python考试编程题
  9. 【廖雪峰Python学习笔记】函数式编程
  10. (C++)1018 锤子剪刀布