1.Android 权限分级
Android 6.0之前只有安装时权限,Android 6.0之后,增加了权限分级,分为4种
normal:低风险权限,只要申请了就可以使用(在AndroidManifest.xml中添加标签),安装时不需要用户确认;
dangerous:高风险权限,安装时需要用户的确认才可使用;
signature:只有当申请权限的应用程序的数字签名与声明此权限的应用程序的数字签名相同时(如果是申请系统权限,则需要与系统签名相同),才能将权限授给它;
signatureOrSystem:签名相同,或者申请权限的应用为系统应用(在system image中)。
2.权限定义:在源码frameworks/base/core/res/AndroidManifest.xml
NormalPermission:
DangerousPermission
3.权限管理
权限组的权限是在运行时授予的,授权方式使用packageManager的grantRuntimePermission()
pm.grantRuntimePermission(packageName, permission, Process.myUserHandle());
取消授权使用packageManager的revokepackageManager的grantRuntimePermission()
pm.revokeRuntimePermission(packageName, permission, Process.myUserHandle());
特殊权限(System_alert_window)使用AppOpsManager
AppOpsManager mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
PackageManager pm = context.getPackageManager();
PackageInfo mPackageInfo;
try {
mPackageInfo = pm.getPackageInfo(packageName,
PackageManager.MATCH_DISABLED_COMPONENTS |
PackageManager.MATCH_ANY_USER |
PackageManager.GET_SIGNATURES |
PackageManager.GET_PERMISSIONS);
PermissionInfo permissionInfo = pm.getPermissionInfo(permission, 0);
String appOp = PLATFORM_PACKAGE_NAME.equals(permissionInfo.packageName)
? AppOpsManager.permissionToOp(permissionInfo.name) : null;
if(appOp != null){
mAppOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
mPackageInfo.applicationInfo.uid, packageName,
AppOpsManager.MODE_ERRORED);
Log.d(TAG, "mAppOpsManagerrevokeRuntimePermission");
} else {
pm.revokeRuntimePermission(packageName, permission, Process.myUserHandle());
Log.d(TAG, "revokeRuntimePermission");
}
} catch (PackageManager.NameNotFoundException e){
Log.d(TAG, "NameNotFoundException");
e.printStackTrace();
}
4.AppopsManager介绍
Appopsmanager是在android4.3引入的(API for interacting with “application operation” tracking.)
This API is not generally intended for third party application developers; most features are only available to system applications.
这个类只有拥有系统权限的应用才可以使用,是用来做权限管理的。
5.权限检测:
权限组检测:
hasPermission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, packageName));
特殊权限(System_alert_window)使用AppOpsManager
hasPermission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, packageName));
PackageManager pm = context.getPackageManager();
AppOpsManager mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
PackageInfo mPackageInfo;
boolean hasPermission = false;
try {
mPackageInfo = pm.getPackageInfo(packageName,
PackageManager.MATCH_DISABLED_COMPONENTS |
PackageManager.MATCH_ANY_USER |
PackageManager.GET_SIGNATURES |
PackageManager.GET_PERMISSIONS);
PermissionInfo permissionInfo = pm.getPermissionInfo(permission, 0);
String appOp = PLATFORM_PACKAGE_NAME.equals(permissionInfo.packageName)
? AppOpsManager.permissionToOp(permissionInfo.name) : null;
if (appOp != null) {
Log.d(TAG, "appOp" + appOp);
int checkResult = mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
mPackageInfo.applicationInfo.uid, packageName);
Log.d(TAG, "checkResult" + checkResult);
if (checkResult == AppOpsManager.MODE_ALLOWED) {
hasPermission = true;
} else if (checkResult == AppOpsManager.MODE_ERRORED) {
hasPermission = false;
}
但是还有自定义权限无法获取名称。以及一些不可改变的权限,无法去开关,过滤掉就好。
系统应用无法开关权限。
5.判断是否是系统应用
//judge a app is a system app
public static final boolean isSystemApp(PackageInfo packageInfo){
return ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) !=0);
}