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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
不错!
[***.144.177.141]2024年04月22日 11时52分11秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
mysql知识总结
2019-04-29
VUE:不是内部或外部命令,也不是可运行的程序或批处理文件解决方法
2019-04-29
vue:报错“Extra semicolon“解决
2019-04-29
java:数据类型
2019-04-29
Java:对象的引用类型:强引用、软引用、弱引用、和虚引用
2019-04-29
react消息订阅与发布机制
2019-04-29
React路由(1)-前端路由的基石 history
2019-04-29
React路由(2)-路由的基本使用
2019-04-29
React路由(3)-一般组件和路由组件
2019-04-29
C# richTextBox显示不同颜色文字
2019-04-29
C#连接ACCESS
2019-04-29
c#richtextbox的内容保存为TXT文本
2019-04-29
Windows.old可以删除吗?
2019-04-29
VS2012类视图查看函数
2019-04-29
VS项目添加附加目录
2019-04-29
VS找到汇编指令对应的16进制字符
2019-04-29
VS生成依赖项关系图
2019-04-29
VC6.0栈回溯
2019-04-29