Android M 小米手机 Settings.canDrawOverlays(悬浮窗权限:SYSTEM_ALERT_WINDOW)一直返回false的问题
发布日期:2021-06-28 19:09:25 浏览次数:2 分类:技术文章

本文共 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个小程序」,即可免费领取享有导入就能跑的微信小程序

在这里插入图片描述

转载地址:https://blog.csdn.net/xudailong_blog/article/details/89364625 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android webview设置背景透明,去掉白色
下一篇:Android 8.0 华为手机 桌面应用图标显示圆形适配方案

发表评论

最新留言

不错!
[***.144.177.141]2024年04月22日 11时52分11秒