Android权限

简介: Android权限【5月更文挑战第3天】

权限


我们知道,Android应用都运行在沙盒中,默认情况下这些应用只能访问他们自己的域,即自己的文件和非常少量的系统服务。为了能够和系统或者其他应用交互,app就需要申请额外的一些权限。

permission(权限)实际上就是一个简单的字串,申明需要做哪些类型的操作。

Android系统预置了很多权限

权限的定义是在/frameworks/base/core/res/AndroidManifest.xml

如果要看系统内已知的权限列表,可以使用pm list permissions命令:

加上 -f选项,可以打印出定义权限的package、label、description和protection level。


权限管理


在应用安装的时候,PackageManagerService就对每个应用授予了权限。package manager管理了一个数据库,用来维护预置或者用户安装的package。维护的内容包括:安装路径,版本号,签名证书,每个package拿到的权限列表和一个在本设备上定义的所有权限列表。这个package数据库保存在/data/system/packages.xml路径下,每当有应用安装,更新或者卸载的时候都会更新这个xml文件。


权限组


在权限定义文件里会定义权限组,然后在单独的权限中指定该权限属于哪个权限组。

  • 如果应用没有获得与当前申请的权限在同一权限组的其他权限的授权,那么系统将以这个权限组的描述信息去提示用户,而不是具体申请的权限的描述信息。比如,一个应用申请了READ_CONTACTS权限,系统会提示用户”应用需要访问设备的联系人(包含读写)”,如果用户同意授权,系统只会赋予应用之前申请的权限(在这里就只是READ_CONTACTS)。
  • 如果应用已经获得了与正在申请的权限同一个权限组的其他权限的授权,那么系统会自动将正在申请的权限授予应用,不需要任何与用户的交互行为。比如,如果一个应用之前已经获得了READ_CONTACTS权限的授权,那么在之后应用请求WRITE_CONTACTS权限时,系统会自动将该权限授予应用。


权限保护等级ProtectionLevel


protectionLevel是定义权限时的一个重要属性,它表示一个权限的级别,在很大程度上它也决定了一个权限被授权的方式(由系统安装时自动授权或者由用户来决定是否授权)。 protectionLevel可以分为两类:基础权限级别附加权限级别

基础权限级别

normal

这是个默认值,也就是没有指定protectionLevel的权限默认获得此level。它表示这是一个对系统和其他应用低风险的权限。有该标记的权限是不需要用户确认就可以直接赋予应用程序的

dangerous

较高风险的权限。该标记的权限一般涉及到访问用户的隐私数据或者其他一些控制设备的行为,可能会给用户带来影响。所以系统不会自动授权这类权限,而是会弹出对话框告诉用户,由用户进行选择是否授予权限。

signature

如果请求权限的app与声明权限的app签名一致,系统会自动赋予权限,而不会通知用户或者征求用户的同意。 否则需要通过intent将用户引导到权限管理界面由用户决定是否授权。

这属于最高级的权限等级,因为它需要有加密密钥的拥有权,而这个密钥只有这个app或者系统平台才会拥有。这也就意味着其他人无法随意使用这个权限。系统内置的signature权限一般都是由管理设备的系统App使用,也就是需要系统签名。

signatureOrSystem

相当于signature | privileged

这个权限等级有两种应用可以自动获取该类型权限的授权:

与定义这个权限的apk拥有相同的签名的应用(这一点和Signature类型的权限相同)。

在/system/priv-app目录下的应用(即拥有超级权限的系统应用)。

这可以让制造商的预置应用即使没有与该权限一致的签名也可以通过作为系统应用去使用该权限。

附加权限级别

除了基础权限级别的其他权限级别都属于附加权限级别。它们必须附加在基础权限级别上使用。从目前系统定义的权限来看,附加权限级别基本都是与signature基础权限级别搭配使用。

可以理解为附加权限级别是在为signature级别的权限开后门,使signature级别的权限在特定的条件下能够授权给特定类型的应用。

  • privileged:只能与signature同时使用。signature | privileged与signatureOrSystem意义相同。
  • system:与privileged相同,是privileged的老版本。
  • development:development applications可以被自动授予此权限。
  • appop:此类权限会与AppOpsManager来配合完成对应用操作的限制(AppOpsManager在后面的小节介绍)。
  • pre23:应用请求此类权限后,系统将在应用安装时自动授权给那些targetSdkVersion在23(Android 6.0)以下的应用。
  • installer:此类权限自动被授权给那些负责安装apk的系统app。
  • verifier:此类权限自动被授权给那些负责验证apk的系统app。
  • preinstalled:此类权限可以自动被授权给任何预安装在system image中的app,不只是privileged app。
  • setup:此类权限自动被授予安装向导app。


AppOps


初次接触Appops是因为,现在国内很多App都要过多的权限,比如随便一个App都要访问手机号,不给它权限的话它就退出不让你使用。后来发现,可以通过Appops默默修改权限,比如第一次打开App的时候给它所有权限,然后再用Appops偷偷把权限禁用掉,这样App可以正常打开使用,但它也偷不到对应的信息了。

adb shell appops set com.tencent.gamehelper.smoba READ_EXTERNAL_STORAGE ignore

这样就禁掉了腾讯游戏对设备存储的访问。当然除了这种用法,对于一些特殊权限比如悬浮窗权限的授权也可以使用AppOps来解决。

AppOps 是什么

Appops是Application Operations的简称,是关于应用权限管理的一套方案,但这里的应用指的是系统应用,这些API不对第三方应用开放。Google从4.3开始推出Appops, 但一直到最新的Android N都没有在Settings里面开放Appops的入口,但这套方案却一直在后台默默的运行着。

// 允许执行相关权限
public static final int MODE_ALLOWED = 0;
// 表示当前应用没有此权限,如果尝试使用该权限,就会静态地进入失败状态,出现应用莫名其妙crash。
public static final int MODE_IGNORED = 1;
// 表示当前应用没有此权限,并且如果使用此权限会导致SecurityException  
public static final int MODE_ERRORED = 2;
// 表示默认值,应该使用其默认的安全检查。这个模式并不常用,它应该和appop权限一起使用,并且调用者必须显式地检查和使用它
public static final int MODE_DEFAULT = 3;

AppOps工作流程

Appops工作框架如下

 

 

可以看到Appops的两个重要组成部分是AppOpsManagerAppOpsService,它们是典型的客户端和服务端设计,通过Binder跨进程调用。

AppOpsService是做最终检查的系统服务,它的注册名字是appops,应用可以类似于mAppOps=(AppOpsManager)getContext().getSystemService(Context.APP_OPS_SERVICE);的方式来获取这个服务。

AppOpsManager提供了接口,访问AppOpsService的核心方法。

AppOpsService是在AMS构造函数中启动的:

mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
                                 new IAppOpsCallback.Stub() {
    @Override 
  public void opChanged(int op, int uid, String packageName) {
      if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
            if (mAppOpsService.checkOperation(op, uid, packageName) 
          != AppOpsManager.MODE_ALLOWED) {
                runInBackgroundDisabled(uid);
            }
        }
    }
});

Api使用

AppOpsManager提供标准的API供APP调用,但google有明确说明,大部分只针对系统应用。但是想使用的话,可以尝试把Android源码里AppOpsManager.java打包一下,把jar包导入自己的工程,就可以使用了。

int checkOp(Stringop, int uid,StringpackageName)Op对应一个权限操作,该接口来检测应用是否具有该项操作权限。

int noteOp(Stringop, int uid,StringpackageName)和checkOp基本相同,但是在检验后会做记录。

int checkOpNoThrow(Stringop, int uid,StringpackageName)和checkOp类似,但是权限错误,不会抛出SecurityException,而是返回AppOpsManager.MODE_ERRORED。

int noteOpNoThrow(Stringop, int uid,StringpackageName)  类似noteOp,但不会抛出SecurityException。

void setMode( int code, int uid, String packageName, int mode)  code代表具体的操作权限,mode代表要更改成的类型(允许/禁止/提示)

mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);

mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, getAppUid(packageGaode), packageGaode, AppOpsManager.MODE_ALLOWED);


private int getAppUid(String packageName) {
  int uid = 0;
  try {
    PackageManager pm = mContext.getPackageManager();
    ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
    uid = ai.uid;
  } catch (NameNotFoundException e) {
    e.printStackTrace();
  }
  return uid;
}



目录
相关文章
|
4月前
|
存储 安全 Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
【8月更文挑战第13天】随着Android系统的更新,权限管理变得至关重要。尤其从Android 6.0起,引入了动态权限请求,增强了用户隐私保护并要求开发者实现更精细的权限控制。本文采用问答形式,深入探讨动态权限请求机制与最佳实践,并提供示例代码。首先解释了动态权限的概念及其重要性;接着详述实现步骤:定义、检查、请求权限及处理结果;最后总结了六大最佳实践,包括适时请求、解释原因、提供替代方案、妥善处理拒绝情况、适应权限变更及兼容旧版系统,帮助开发者打造安全易用的应用。
85 0
|
3月前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
79 2
|
7月前
|
Java Shell Android开发
android 权限申请
android 权限申请
125 5
|
7月前
|
存储 Java API
Android系统 文件访问权限笔记
Android系统 文件访问权限笔记
634 1
|
7月前
|
存储 缓存 安全
Android系统 应用存储路径与权限
Android系统 应用存储路径与权限
404 0
Android系统 应用存储路径与权限
|
7月前
|
安全 Android开发 数据安全/隐私保护
Android中的动态权限请求与最佳实践
【4月更文挑战第14天】 在现代安卓应用开发中,用户隐私和安全被赋予了前所未有的重要性。随着Android 6.0(API级别23)引入的运行时权限模型,开发者必须更加细致地处理权限请求,以确保应用功能的完整性同时不侵犯用户的隐私。本文将深入探讨如何在Android应用中实现动态权限请求,分析常见问题,并提供一系列最佳实践,以帮助开发者优雅地处理这一挑战。
450 5
|
7月前
|
Android开发 开发者
Android打开开发者权限
Android打开开发者权限
79 0
|
7月前
|
Android开发
Android 9.0中sdcard 的权限和挂载问题
Android 9.0中sdcard 的权限和挂载问题
102 0
|
7月前
|
Android开发
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。 【5月更文挑战第2天】
361 0
|
7月前
|
Android开发
android 12 U盘 /mnt/media_rw 下读取文件异常 没有权限
android 12 U盘 /mnt/media_rw 下读取文件异常 没有权限
311 0