|
Android 7实现具体权限管理思路
发表于 2017-7-14 16:53:02
浏览:11770
|
回复:1
打印
只看该作者
[复制链接]
楼主
本帖最后由 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。以下代码为我的修改实现:
- UserManager userManager = mContext.getSystemService(UserManager.class);
- for (UserHandle user : userManager.getUserProfiles()) {
- List<PackageInfo> apps = mContext.getPackageManager()
- .getInstalledPackagesAsUser(PackageManager.GET_PERMISSIONS,
- user.getIdentifier());
- final int N = apps.size();
- for (int i = 0; i < N; i++) {
- PackageInfo app = apps.get(i);
- if (app.requestedPermissions == null) {
- continue;
- }
- // 遍历APP权限
- for (int j = 0; j < app.requestedPermissions.length; j++) {
- String requestedPerm = app.requestedPermissions[j];
- // 判断APP是否申请当前权限
- if (requestedPerm.equals(mPermissionName)) {
- mPermissionApps.add(new PermissionApp(
- app.packageName,
- app.applicationInfo.loadLabel(mPm),
- app.applicationInfo.loadIcon(mPm),
- app.requestedPermissionsFlags[j]));
- break;
- }
- }
- }
- }
复制代码 PermissionApp的定义如下:
- public static final class PermissionApp {
- public String packageName;
- // APP显示名称
- public CharSequence label;
- public Drawable icon;
- // 记录APP授权状态
- public int mode;
- public PermissionApp(String packageName, CharSequence label, Drawable icon, int mode) {
- this.packageName = packageName;
- this.label = label;
- this.icon = icon;
- this.mode = mode;
- }
- }
复制代码 在权限管理中,重要的操作就是判断APP是否已经被授予权限,如果只是简单的判断的话可以通过
- // PermissionApp pa;
- (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类的实现。
|
|