本文共 3761 字,大约阅读时间需要 12 分钟。
因为项目中使用到了悬浮窗,而在Android 系统M以上,使用悬浮窗是需要用到SYSTEM_ALERT_WINDOW这个属性。
主要是根据以下文章进行了参考
(一)
下面这篇文章使用到的代码:
public static boolean checkFloatPermission(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return true; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { try { Class cls = Class.forName("android.content.Context"); Field declaredField = cls.getDeclaredField("APP_OPS_SERVICE"); declaredField.setAccessible(true); Object obj = declaredField.get(cls); if (!(obj instanceof String)) { return false; } String str2 = (String) obj; obj = cls.getMethod("getSystemService", String.class).invoke(context, str2); cls = Class.forName("android.app.AppOpsManager"); Field declaredField2 = cls.getDeclaredField("MODE_ALLOWED"); declaredField2.setAccessible(true); Method checkOp = cls.getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class); int result = (Integer) checkOp.invoke(obj, 24, Binder.getCallingUid(), context.getPackageName()); return result == declaredField2.getInt(cls); } catch (Exception e) { return false; } } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); if (appOpsMgr == null) return false; int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window", android.os.Process.myUid(), context .getPackageName()); return mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_IGNORED; } else { return Settings.canDrawOverlays(context); } }}
结果:
直接CV进去,发现并没有任何效果,使用的测试手机是红米Note 5 Android 8.1 ,然后又搜了好久,搜到了另外一篇文章:
(二)
下面是在onActivityResult进行的操作:
Handler mHandler;@Overrideprotected void onActivityResult(final int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (mHandler == null){ mHandler = new Handler(Looper.getMainLooper()); } mHandler.postDelayed(new Runnable() { @Override public void run() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == PermissionRequestCode){ boolean nOpen = Settings.canDrawOverlays(XXXActivity.this); if (nOpen){ //开启 }else { //关闭 } Log.e("PermissionRequest", "open = " + nOpen); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == PermissionRequestCode){ AppOpsManager appOpsMgr = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window", android.os.Process.myUid(), getPackageName()); if (mode == 1 || mode == 0){ //权限已开起 }else if (mode == 2 || mode== 3 ){ //权限已关闭 } Log.e("PermissionRequest", "mode = " + mode); //此方法不可行,亲测华为8.0手机 未申请状态时 也返回1 } } }, 500);}
在上面的代码虽然是有两段进行判断是否关闭权限的,但是在红米Note5 Android OS 8.1上,在使用AppOpsManager这个类返回的是mode状态为3,而在使用Settings.canDrawOverlays这个方法上面返回的nOpen是true,所以到这里,我就用了第一个方法。
总的来说Settings.canDrawOverlays这个方法本没有错,但是在直接调用onActivityResult这个方法返回的一直是false,这时候我们需要用到延迟个500毫秒进行状态的获取,不信你试试。
关注「蛇崽网盘教程资源」公众号 ,在微信后台回复「领取资源」,获取IT资源200G干货大全。
更多资源请访问:
关注「蛇崽网盘教程资源」公众号 ,在微信后台回复「领取资源」,获取IT资源200G干货大全。
在微信后台回复「130个小程序」,即可免费领取享有导入就能跑的微信小程序
转载地址:http://bbxkf.baihongyu.com/