Firefly开源社区

Android 7实现具体权限管理思路

517

积分

1

威望

0

贡献

社区版主

Rank: 7Rank: 7Rank: 7

积分
517
发表于 2017-7-14 16:53:02     
本帖最后由 rany 于 2017-7-14 16:53 编辑

原生Android N中有自带的权限管理功能,在“设置->应用->应用信息->权限"中,这是简化的设置,只能对每个应用进行权限组的管理,一些特殊的权限也没有进行统一的管理。国内的很多ROM实现了对各个具体权限的管理,如MIUI。这里我简单的说明一下对具体权限管理的思路。
首先,要实现对具体权限管理要先了解Android系统对权限的定义。Android系统把权限分为了权限(Permission)和权限组(Permission Group)两部分。权限可以归类到一个具体的权限组中,有一些权限没有属于特定的组。具体权限的定义可以参考Google官方定义的文档(国内可访问):https://developer.android.google.cn/reference/android/Manifest.permission.html  权限组的定义:https://developer.android.google.cn/reference/android/Manifest.permission_group.html
其中部分权限与权限组的关联可参考:https://developer.android.google.cn/guide/topics/permissions/requesting.html 原生Android 7中管理的就是权限组。通过这些定义可以生成或定制自己想要管理的权限列表。

然后是要知道如何获取申请这个权限的所有App。在Android系统源码中有获取申请这个权限组下的权限所有App的实现源码,在packages/apps/PackageInstaller/包中,可以根据此源码实现获取每个权限的所有申请App。以下代码为我的修改实现:
  1. UserManager userManager = mContext.getSystemService(UserManager.class);
  2. for (UserHandle user : userManager.getUserProfiles()) {
  3.     List<PackageInfo> apps = mContext.getPackageManager()
  4.             .getInstalledPackagesAsUser(PackageManager.GET_PERMISSIONS,
  5.                     user.getIdentifier());
  6.     final int N = apps.size();
  7.     for (int i = 0; i < N; i++) {
  8.         PackageInfo app = apps.get(i);
  9.         if (app.requestedPermissions == null) {
  10.             continue;
  11.         }
  12.         // 遍历APP权限
  13.         for (int j = 0; j < app.requestedPermissions.length; j++) {
  14.             String requestedPerm = app.requestedPermissions[j];
  15.             // 判断APP是否申请当前权限
  16.             if (requestedPerm.equals(mPermissionName)) {
  17.                 mPermissionApps.add(new PermissionApp(
  18.                         app.packageName,
  19.                         app.applicationInfo.loadLabel(mPm),
  20.                         app.applicationInfo.loadIcon(mPm),
  21.                         app.requestedPermissionsFlags[j]));
  22.                 break;
  23.             }      
  24.         }
  25.     }
  26. }
复制代码
PermissionApp的定义如下:

  1. public static final class PermissionApp {
  2.         public String packageName;
  3.         // APP显示名称
  4.         public CharSequence label;
  5.         public Drawable icon;
  6.         // 记录APP授权状态
  7.         public int mode;

  8.         public PermissionApp(String packageName, CharSequence label, Drawable icon, int mode) {
  9.             this.packageName = packageName;
  10.             this.label = label;
  11.             this.icon = icon;
  12.             this.mode = mode;
  13.         }
  14.     }
复制代码
在权限管理中,重要的操作就是判断APP是否已经被授予权限,如果只是简单的判断的话可以通过
  1. // PermissionApp pa;
  2. (pa.mode & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
复制代码
进行的判断。然而对于Android 6.0后的运行时申请的权限,我们一般要多一个可以设置的选项 提示,而不只是允许与禁止。Android中跟运行时申请的权限相关的两个java类为AppOpsManager和AppOpsService,在Android源码的frameworks/base/core/java/android/app中。AppOpsManager中定义了checkOp、checkOpNoThrow、noteOp和noteOpNoThrow等权限验证方法。同时PackageInfo类中的requestedPermissionsFlags也记录了App相应的权限的状态。
最后就是权限的设置了。权限的设置可使用AppOpsManager的setUidMode和PackageManger的updatePermissionFlags结合设置。可以参考packages/apps/PackageInstaller中的com.android.packageinstaller.permission.model.AppPermissionGroup类的实现。



回复

使用道具 举报

891

积分

76

威望

51

贡献

超级版主

Rank: 8Rank: 8

积分
891
发表于 2017-8-5 17:15:46     
挺实用的,感谢分享
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表