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

时间:2025-01-28 08:27:55

需求确认:

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

 

问题场景:

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

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

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

 

解决:

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

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

1.在AndroidManifest中添加权限

   <uses-permission android:name=".GET_APP_OPS_STATS" />
   <uses-permission android:name=".MANAGE_APP_OPS_MODES" />
   <uses-permission android:name=".SYSTEM_ALERT_WINDOW"/>

         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 = "";
		PackageInfo packageInfo = null;
		int appOpMode = -1;
		try {
			packageInfo = ().getPackageInfoAsUser(packageName,
					PackageManager.MATCH_DISABLED_COMPONENTS |
							PackageManager.GET_SIGNING_CERTIFICATES |
							PackageManager.GET_PERMISSIONS, ());
		} catch ( e) {
			();
		}
		if (packageInfo != null){
			AppOpsManager appOpsManager = (AppOpsManager) (Context.APP_OPS_SERVICE);
			final List<> packageOps = (APP_OPS_OP_CODES);
			final int packageOpsCount = packageOps != null ? () : 0;
			for (int i = 0; i < packageOpsCount; i++) {
				final  packageOp = (i);
				if ((packageName,())){
					appOpMode = ().get(0).getMode();
				}
			}
		}
		return appOpMode == AppOpsManager.MODE_ALLOWED;

	}

         3.设置悬浮窗权限

	public static void setSystemAlertWindowAllowed(Context context) {
		String packageName = "";
		PackageInfo packageInfo = null;
		try {
			packageInfo = ().getPackageInfoAsUser(packageName,
					PackageManager.MATCH_DISABLED_COMPONENTS |
							PackageManager.GET_SIGNING_CERTIFICATES |
							PackageManager.GET_PERMISSIONS, ());
		} catch ( e) {
			();
		}
		/*AppOpsManager.MODE_ALLOWED 允许
		AppOpsManager.MODE_DEFAULT 禁止*/
		if (packageInfo != null){
			AppOpsManager appOpsManager = (AppOpsManager) (Context.APP_OPS_SERVICE);
			(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
					, packageName, AppOpsManager.MODE_ALLOWED);
		}
	}

备注:

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

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