当前位置:   article > 正文

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

appopsmanager

需求确认:

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

 

问题场景:

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

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

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

 

解决:

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

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

1.在AndroidManifest中添加权限

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

         2.查询有无权限

  1. private static final int APP_OPS_OP_CODE = AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
  2. public static final int[] APP_OPS_OP_CODES = {
  3. APP_OPS_OP_CODE,
  4. };
  5. public static boolean checkSystemAlertWindowAllowed(Context context){
  6. String packageName = "com.xxx.xxx";
  7. PackageInfo packageInfo = null;
  8. int appOpMode = -1;
  9. try {
  10. packageInfo = context.getPackageManager().getPackageInfoAsUser(packageName,
  11. PackageManager.MATCH_DISABLED_COMPONENTS |
  12. PackageManager.GET_SIGNING_CERTIFICATES |
  13. PackageManager.GET_PERMISSIONS, UserHandle.myUserId());
  14. } catch (PackageManager.NameNotFoundException e) {
  15. e.printStackTrace();
  16. }
  17. if (packageInfo != null){
  18. AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
  19. final List<AppOpsManager.PackageOps> packageOps = appOpsManager.getPackagesForOps(APP_OPS_OP_CODES);
  20. final int packageOpsCount = packageOps != null ? packageOps.size() : 0;
  21. for (int i = 0; i < packageOpsCount; i++) {
  22. final AppOpsManager.PackageOps packageOp = packageOps.get(i);
  23. if (TextUtils.equals(packageName,packageOp.getPackageName())){
  24. appOpMode = packageOp.getOps().get(0).getMode();
  25. }
  26. }
  27. }
  28. return appOpMode == AppOpsManager.MODE_ALLOWED;
  29. }

         3.设置悬浮窗权限

  1. public static void setSystemAlertWindowAllowed(Context context) {
  2. String packageName = "com.xxx.xxx";
  3. PackageInfo packageInfo = null;
  4. try {
  5. packageInfo = context.getPackageManager().getPackageInfoAsUser(packageName,
  6. PackageManager.MATCH_DISABLED_COMPONENTS |
  7. PackageManager.GET_SIGNING_CERTIFICATES |
  8. PackageManager.GET_PERMISSIONS, UserHandle.myUserId());
  9. } catch (PackageManager.NameNotFoundException e) {
  10. e.printStackTrace();
  11. }
  12. /*AppOpsManager.MODE_ALLOWED 允许
  13. AppOpsManager.MODE_DEFAULT 禁止*/
  14. if (packageInfo != null){
  15. AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
  16. appOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
  17. packageInfo.applicationInfo.uid, packageName, AppOpsManager.MODE_ALLOWED);
  18. }
  19. }

备注:

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/261365
推荐阅读
相关标签
  

闽ICP备14008679号