需求确认:
最近产品在系统升级方面加了一个强制升级的需求,安装完成后需要通过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);
}
}
备注:
因为公司项目是系统级的升级,优先级高,所以是在用户不知情的情况下将权限设为允许。
希望各位朋友尊重用户权限,根据自己项目展示出合理的交互,让用户自己授权!!!