Android 7实现具体权限管理思路
本帖最后由 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;
// 判断APP是否申请当前权限
if (requestedPerm.equals(mPermissionName)) {
mPermissionApps.add(new PermissionApp(
app.packageName,
app.applicationInfo.loadLabel(mPm),
app.applicationInfo.loadIcon(mPm),
app.requestedPermissionsFlags));
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类的实现。
挺实用的,感谢分享
页:
[1]