赞
踩
需求确认:
最近产品在系统升级方面加了一个强制升级的需求,安装完成后需要通过dialog提示用户重启,如果当即拒绝,一个小时后继续弹出此dialog。
问题场景:
首先想到的是通过AlarManager定时通知Receiver,再由Receiver通知Service调起dialog。
但是在调试过程中发现,应用进入后台或者被杀死后,Service是无法调起dialog的。期间也尝试用ActivityDialog的方式,但是也无济于事。
最终在设置中发现了悬浮窗权限,设为允许后可以正常弹出,至此发现问题原因。
解决:
因为在Android中是没有悬浮窗权限的系统级的授权弹框,所以我们就要想办法在代码中设置。
通过分析settings源码,最终提取了以下两个方法用户查询和设置悬浮窗权限。
1.在AndroidManifest中添加权限
- <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
- <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
- <uses-permission android:name="android.permission.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 = "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<AppOpsManager.PackageOps> 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);
- }
- }
备注:
因为公司项目是系统级的升级,优先级高,所以是在用户不知情的情况下将权限设为允许。
希望各位朋友尊重用户权限,根据自己项目展示出合理的交互,让用户自己授权!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。