Android Permission介绍

权限介绍

Android系统上每一个独立的应用运行在不同的系统空间,以User ID和Group ID来标识。不同应用之间互相访问数据接口资源,就牵涉到权限问题,本篇对权限问题做一个总结简介。

用户ID和文件访问权限的关系

在我们安装一个新应用的时候,Android系统就会为这个新应用分配一个user ID,这个user ID全局唯一,也就是说不可能存在两个不同的应用在同一个手机设备上拥有相同的user id,并且user id一旦分配好,就不会在变,除非用户卸载重新安装,同一个应用安装在不同的手机上,其user ID不一定相同。
由于Android的安全机制是进程级别的,user id不同,那么其运行的进程也就不同,因此通常来讲两个不同应用无法运行在对方的进程中,除非在 AndroidManifest.xml文件中配置相同的 sharedUserId。配置了相同 sharedUserId的应用在系统层会被看成同一个应用,他们的user id和权限都相同。为了防止恶意程序利用这点,恶意配置一个和目标应用相同的sharedUserId,来做破坏,Android的安全机制还规定了签名一致性。总结来说,想要保证两个不同的应用运行在同一个进程中,必须满足两点:

  • 相同的签名
  • 配置相同的 sharedUserId。

应用产生的数据会和应用的userid对应起来,其他应用是无法正常访问的。但如果使用getSharedPreferences(String, int), openFileOutput(String, int), 或者是 openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory)方法创建一个存储数据文件时,使用了 MODE_WORLD_READABLE 或者 MODE_WORLD_WRITEABLE标志,那么其他应用则对该文件拥有了读/写权限。文件的所有者虽然还是属于创建文件的程序,但它变成了全局可写可读的了。
查看user id可以使用命令

adb shell dumpsys package

比如如果要查看Settings应用的user id可以使用如下命令:

adb shell dumpsys package com.android.settings| grep -A5 userId -b5

得到输出结果入下图:
这里写图片描述
通过上面的输出信息,我们可以看到settings应用的userid 为1000,这个userid比较特殊,特殊在它的值小于10000,通常来用户安装的三方应用userid都会大于10000.settings userid小于10000,是因为它配置了sharedUserId=”android.uid.system”,这样它的userid就与android.uid.system进程相同了。之所以这样配置,是因为Settins应用好多操作都需要有较高的系统权限。

用户权限

权限分类

上面提到了通过配置相同的shareUserId来达到不同应用间的数据共享,但这种做法局限性太大。更通常的做法是通过uses-permission来达到数据共享的目的。当开发一个应用时,如果我们不去配置uses-permission,那么这个应用几乎是什么也做不了,系统没有给应用赋予默认的基础权限,任何操作权限都必须在AndroidManifest.xml文件中声明。这里权限对系统来说,又分为四种:

  • 普通权限(normal permission):即使拥有了该类权限,用户的隐私数据被泄露篡改的风险也很小。
  • 敏感权限(dangerous permission):跟普通权限相反,一旦某个应该获取了该类权限,用户的隐私数据就面临被泄露篡改的风险。比如READ_CONTACTS权限就属于敏感权限。
  • 签名权限(signature permission):该类权限只对拥有相同签名的应用开放,比如手Q程序自定义了一个permission,微信要去访问QQ的某个数据时,必须要拥有该权限,那么手Q在自定义该权限时可以在权限标签中加入android:protectionLevel=”signature” 。然后微信和手Q发布时采用相同的签名,微信就可以申请访问手Q中的某类开放数据。即使其他程序知道了这个开放数据的接口,也在manifest注册申请了权限,但由于签名不同,还是无法访问的。
  • 系统签名权限(signatureOrSystem permission):与 signature permission类似,但它不光要求签名相同,还要求是同类的系统级应用,一般手机厂商开发的预制应用,才会用到该类权限。

可以通过命令

adb shell pm list permissions -d -g

查看当前手机系统的敏感权限。
这里写图片描述
查看上图的输出结果,我们可以看到敏感权限也可以自定义的,比如第一条google的权限。另外这里也引出了 permission-group概念。

权限组-Permission groups

不管是普通权限还是敏感权限,甚至自定义的权限都可以属于一个权限组。但是权限组的的概念还是主要用在敏感权限上,通过它能减少用户授权次数。
如果用户已经对同一个权限组里的某一个权限授权通过,那么该权限组里的其他权限也会被系统认为已经开放,不会二次弹出授权提示框。例如,应用之前请求过READ_CONTACTS 权限,并且系统也授权通故,当此时应用在申请WRITE_CONTACTS权限时,系统会直接开放该权限。

在Android6.0之后,Android对权限管理的更加严苛。普通权限申请跟之前版本一样,只用在AndriodManifest.xml文件里配置即可。但是敏感权限不光要在AndroidManifest.xml文件中声明,还要在代码种提供给用户一个运行时权限许可的接口界面。该功能依赖两个方面:

  • 用户设备系统版本。比如用户手机是4.0系统或者6.0系统。
  • 应用自身设置的targetSdkVersion。

比如用户手机系统是6.0,应用的targetSdkVersion设置为23,申请的是敏感权限,那么系统会强制要求运行时权限检查,如果此时AndroidManifest.xml文件中声明了敏感权限,但没有在代码中为用户添加运行时权限检查的入口,那么申请的敏感权限是根本获取不到的。如果系统虽然是Android6.0的,但应用的targetSdkVersion设置为22或者更低,则权限检查方案跟之前的版本一样,系统不会强制要求运行时权限检查。
Android6.0之后新应用的开发需要特别注意用户可以随时控制权限的开放与否,比如用户可能在安装应用的时候将应用申请的权限都许可了,但过了一段时间,用户可能会在在setting里又将申请的某些权限关闭,更极端的case,用户在使用应用的过程中,切换到权限管理界面将应用的某些权限关闭,这些case都需要引在开发时兼顾到。

权限问题实例

前面介绍了权限相关的知识,下面用一个最近碰到的权限问题bug来看看如何debug权限问题。

bug描述:

用户接受一条附件为gif图片的彩信后,用gallery打开浏览该图片,可以正常浏览,点击设置菜单,试图将该图片设置为壁纸,或者联系人头像时,没有反应。复现场景如下图
这里写图片描述

bug分析:

从现象看无FC,系统也正常弹出了选择应用框,但点击则没反应。直观现象暂时猜不出头绪,转而抓取log,则问题一目了然。
这里写图片描述
Log明确的显示是权限问题:

01-03 16:08:13.88
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值