| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> [Android]从canDrawOverlays权限获取错误说起 -> 正文阅读 |
|
[移动开发][Android]从canDrawOverlays权限获取错误说起 |
从Settings.canDrawOverlays到Binder.getCallingPid 在调试程序的时候,发现一个奇怪的问题,在主线程调用Settings.canDrawOverlays判断是否有悬浮权限的结果和在另外一个service线程中调用Settings.canDrawOverlays的结果不一样,奇怪。 事出反常必有妖,我们去看看谁在作怪。 查看其定义 frameworks/base/core/java/android/provider/Settings.java 2225??? public static boolean canDrawOverlays(Context context) { 2226??????? return Settings.isCallingPackageAllowedToDrawOverlays(context, Process.myUid(), 2227??????????????? context.getOpPackageName(), false); 2228??? } 再调用 13247??? public static boolean isCallingPackageAllowedToDrawOverlays(Context context, int uid,
13248??????????? String callingPackage, boolean throwException) {
13249??????? return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid,
13250??????????????? callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
13251??????????????? PM_SYSTEM_ALERT_WINDOW, false);
13252??? }
13277??? public static boolean isCallingPackageAllowedToPerformAppOpsProtectedOperation(Context context,
13278??????????? int uid, String callingPackage, boolean throwException, int appOpsOpCode, String[]
13279??????????? permissions, boolean makeNote) {
13280??????? if (callingPackage == null) {
13281??????????? return false;
13282??????? }
13283
13284??????? AppOpsManager appOpsMgr = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
13285??????? int mode = AppOpsManager.MODE_DEFAULT;
13286??????? if (makeNote) {
13287??????????? mode = appOpsMgr.noteOpNoThrow(appOpsOpCode, uid, callingPackage);
13288??????? } else {
13289??????????? mode = appOpsMgr.checkOpNoThrow(appOpsOpCode, uid, callingPackage);
13290??????? }
13291
13292??????? switch (mode) {
13293??????????? case AppOpsManager.MODE_ALLOWED:
13294??????????????? return true;
13295
13296??????????? case AppOpsManager.MODE_DEFAULT:
13297??????????????? // this is the default operating mode after an app's installation
13298??????????????? // In this case we will check all associated static permission to see
13299??????????????? // if it is granted during install time.
13300??????????????? for (String permission : permissions) {
13301??????????????????? if (context.checkCallingOrSelfPermission(permission) == PackageManager
13302??????????????????????????? .PERMISSION_GRANTED) {
13303??????????????????????? // if either of the permissions are granted, we will allow it
13304??????????????????????? return true;
13305??????????????????? }
13306??????????????? }
13307
13308??????????? default:
13309??????????????? // this is for all other cases trickled down here...
13310???? ???????????if (!throwException) {
13311?????? ?????????????return false;
13312??????????????? }
13313??????? }
添加log,发现是context.checkCallingOrSelfPermission(permission)
的结果在不同线程里不一样, 753??? public int checkCallingOrSelfPermission(String permission) {
754??????? return mBase.checkCallingOrSelfPermission(permission);
755??? }
1786??? public int checkCallingOrSelfPermission(String permission) {
1787??????? if (permission == null) {
1788??????????? throw new IllegalArgumentException("permission is null");
1789??????? }
1790
1791??????? return checkPermission(permission, Binder.getCallingPid(),
1792??????????????? Binder.getCallingUid());
1793??? }
这里可以看到,使用了Binder.getCallingPid()和Binder.getCallingUid()作为参数,在碰到的问题中,次线程是通过Binder调起的服务,所以其Binder.getCallingPid()和主线程不一样,是调用者进程的PID,就是这里的差异,导致了在同一个进程中,不同线程的调用结果不一样, 我们可以使用checkSelfPermission(“android.permission.SYSTEM_ALERT_WINDOW”)去判断权限, 或者使用Binder. clearCallingIdentity(); 把调用信息设置为当前进程后再调用Settings.canDrawOverlays方法。 回过头来看,不同线程的执行结果不一样,肯定是有线程差异在影响,我们应当对Binder的线程情况及Binder.getCallingPid有意识。对于Binder线程中权限的获取,我们都应当格外注意。 Settings.canDrawOverlays(context) 方法可以说是埋了个坑,一般不会有这个问题,如果有问题,就用上面的方法去处理。 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 10:34:21- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |