Android 查询及设置悬浮窗权限(AppOpsManager )

需求确认:

最近产品在系统升级方面加了一个强制升级的需求,安装完成后需要通过dialog提示用户重启,如果当即拒绝,一个小时后继续弹出此dialog。

 

问题场景:

首先想到的是通过AlarManager定时通知Receiver,再由Receiver通知Service调起dialog。

但是在调试过程中发现,应用进入后台或者被杀死后,Service是无法调起dialog的。期间也尝试用ActivityDialog的方式,但是也无济于事。

最终在设置中发现了悬浮窗权限,设为允许后可以正常弹出,至此发现问题原因。

 

解决:

因为在Android中是没有悬浮窗权限的系统级的授权弹框,所以我们就要想办法在代码中设置。

通过分析settings源码,最终提取了以下两个方法用户查询和设置悬浮窗权限。

1.在AndroidManifest中添加权限

   
   
   

         2.查询有无权限

private static final int APP_OPS_OP_CODE = AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
public static final int[] APP_OPS_OP_CODES = {
			APP_OPS_OP_CODE,
	};
	
public static boolean checkSystemAlertWindowAllowed(Context context){
		String packageName = "com.xxx.xxx";
		PackageInfo packageInfo = null;
		int appOpMode = -1;
		try {
			packageInfo = context.getPackageManager().getPackageInfoAsUser(packageName,
					PackageManager.MATCH_DISABLED_COMPONENTS |
							PackageManager.GET_SIGNING_CERTIFICATES |
							PackageManager.GET_PERMISSIONS, UserHandle.myUserId());
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace();
		}
		if (packageInfo != null){
			AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
			final List packageOps = appOpsManager.getPackagesForOps(APP_OPS_OP_CODES);
			final int packageOpsCount = packageOps != null ? packageOps.size() : 0;
			for (int i = 0; i < packageOpsCount; i++) {
				final AppOpsManager.PackageOps packageOp = packageOps.get(i);
				if (TextUtils.equals(packageName,packageOp.getPackageName())){
					appOpMode = packageOp.getOps().get(0).getMode();
				}
			}
		}
		return appOpMode == AppOpsManager.MODE_ALLOWED;

	}

         3.设置悬浮窗权限

	public static void setSystemAlertWindowAllowed(Context context) {
		String packageName = "com.xxx.xxx";
		PackageInfo packageInfo = null;
		try {
			packageInfo = context.getPackageManager().getPackageInfoAsUser(packageName,
					PackageManager.MATCH_DISABLED_COMPONENTS |
							PackageManager.GET_SIGNING_CERTIFICATES |
							PackageManager.GET_PERMISSIONS, UserHandle.myUserId());
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace();
		}
		/*AppOpsManager.MODE_ALLOWED 允许
		AppOpsManager.MODE_DEFAULT 禁止*/
		if (packageInfo != null){
			AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
			appOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
					packageInfo.applicationInfo.uid, packageName, AppOpsManager.MODE_ALLOWED);
		}
	}

备注:

因为公司项目是系统级的升级,优先级高,所以是在用户不知情的情况下将权限设为允许。

希望各位朋友尊重用户权限,根据自己项目展示出合理的交互,让用户自己授权!!!

你可能感兴趣的:(android,Android,R,Android,11)