[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);
13247 public static booleanisCallingPackageAllowedToDrawOverlays(Context context, intuid,
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 booleanisCallingPackageAllowedToPerformAppOpsProtectedOperation(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 intcheckCallingOrSelfPermission(Stringpermission) {
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 }
我们可以使用checkSelfPermission(“android.permission.SYSTEM_ALERT_WINDOW”)去判断权限,
或者使用Binder. clearCallingIdentity(); 把调用信息设置为当前进程后再调用Settings.canDrawOverlays方法。
回过头来看,不同线程的执行结果不一样,肯定是有线程差异在影响,我们应当对Binder的线程情况及Binder.getCallingPid有意识。对于Binder线程中权限的获取,我们都应当格外注意。
Settings.canDrawOverlays(context) 方法可以说是埋了个坑,一般不会有这个问题,如果有问题,就用上面的方法去处理。
[Android]从canDrawOverlays权限获取错误说起相关推荐
- Android M 动态权限获取
新的权限获取方式除了要求像之前版本一样在AndroidManifest文件中静态申请之外,应用还需根据需要请求权限,方式采用向用户显示一个请求权限的对话框.这些被动态申请的权限可以在系统设置中被手动关 ...
- android临时root权限获取失败,安卓手机为何获取Root权限失败?分析手机Root失败的原因是什么?...
如今,手机预装的APP应用程序实在太多,对于有系统纯净强迫症的用户来说,拿到手机第一件事就是折腾,通过Root或者刷机解决问题,那么我们在获取ROOT权限的时候可能会遇到失败,那么安卓手机为何获取Ro ...
- android电视root权限获取,电视盒子/ 智能电视如何通过ADB获取ROOT权限?
如何通过adb获取root权限(安卓电视盒和智能电视通用)? Android 系统rom里面最主要的就3个文件:boot.img.system.img.userdata.img 其中boot.img ...
- android 如何 root权限获取,如何获取android手机root权限获取
安卓手机的卡与不卡,和是否root无关. 安卓的卡,是其开发时就注定的,其原因如下: 1.内存小/少 手机内存在手机出厂的时候就已经固定了,其总量无法调整,不能像电脑一样加内存条.所以想提升可用内存, ...
- android的ROOT权限获取
关于安卓2.3.6 ROOT的方法在网上搜索了很久,发现很多自己都没有成功ROOT.在这里和大家分享下自己使用移动叔叔ROOT工具ROOT 2.3.6的方法. (本人是安卓新手,很多地方还不太懂,有些 ...
- 东芝AC100 Android上网本Root权限获取
因为需要安装一个便携AP功能的软件,所以需要先获取ROOT权限! ROOTing方法参见:tosh-ac100.wetpaint.com/page/Rooting 1: Instal z4root. ...
- android临时root权限获取失败,获取ROOT权限失败怎么办?
Android手机Root失败原 今Android平台便ROOT 式键ROOT用户通发 者提供ROOT工具简单快捷实现 ROOT包括腾讯手 机关机.360手机助 手.卓师.刷机精灵卓师甜椒及移叔叔 R ...
- 【转】Android权限获取机制与常见权限不足问题分析
转自:http://blog.csdn.net/linweig/article/details/6127488# Android系统是运行在Linux内核上的,Android与Linux分别有自己的一 ...
- Android 9.0模拟器root权限获取
Android 9.0在获取权限时报如下错误 remount of the / superblock failed: Permission denied remount failed 解决方法为: 1 ...
最新文章
- sql server 表索引碎片处理
- [BZOJ 2425] 计数
- centos c++ 找不到头文件mysql.h
- java方法体逻辑不会写怎么办,想自己写框架?不会写Java注解可不行
- delimiters 插值 选项
- Sqoop1使用手册
- RedHat7安装Tomcat
- [转]使用debugger调试JavaScript脚本
- mybatisplus service insert 空指针_c++ 图解层序遍历和逐层打印智能指针建造的二叉树...
- mysql错误1215hy000_MySQL:错误1215(HY000):无法添加外键约束
- RS232 DB9 公头 母头 串口引脚定义
- x80hd装linux,台电X80HD:双系统切换的方法演示_台电 X80HD_平板电脑评测-中关村在线...
- 职称计算机2015年,2015年职称计算机考试题库最新版.doc
- win10截图截屏快捷键 截图截屏工具
- 液晶显示器常见、尺寸、分辨率、点距
- 计算机教研组活动简讯,思中信息技术组教研活动简报
- 中国前十软件公司招聘官网聚合
- 烽火ExMobi引领企业移动应用平台浪潮
- 6个开源项目提高GIS编程技能
- PHP配置连接MSSql数据库