Android 获取判断是否有悬浮窗权限的方法
作者:安地Andy 时间:2023-11-04 22:48:18
现在很多应用都会用到悬浮窗,很多国产rom把悬浮窗权限加入控制了,你就需要判断是否有悬浮窗权限,然后做对应操作。
Android 原生有自带权限管理的,只是被隐藏了。看android源码在android.app下就有个AppOpsManager类。
类说明如下:
/**
* API for interacting with "application operation" tracking.
*
* <p>This API is not generally intended for third party application developers; most
* features are only available to system applications. Obtain an instance of it through
* {@link Context#getSystemService(String) Context.getSystemService} with
* {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
*/
上面说明了只对系统应用有用,rom厂商们应该就是利用这个AppOps机制开放一些权限控制。
我们要判断是否有权限该如何做呢?就只能通过反射去判断了。
AppOpsManager的checkOp方法,就是检测是否有某项权限的方法有这些返回值,分别是允许,忽略,错误和默认:
/**
* Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
* allowed to perform the given operation.
*/
public static final int MODE_ALLOWED = 0;
/**
* Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
* not allowed to perform the given operation, and this attempt should
* <em>silently fail</em> (it should not cause the app to crash).
*/
public static final int MODE_IGNORED = 1;
/**
* Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
* given caller is not allowed to perform the given operation, and this attempt should
* cause it to have a fatal error, typically a {@link SecurityException}.
*/
public static final int MODE_ERRORED = 2;
/**
* Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
* use its default security check. This mode is not normally used; it should only be used
* with appop permissions, and callers must explicitly check for it and deal with it.
*/
public static final int MODE_DEFAULT = 3;
只有MODE_ALLOWED才是确定有权限的。
类里面checkOp方法如下,三个参数分别是操作id,uid和包名:
/**
* Do a quick check for whether an application might be able to perform an operation.
* This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
* or {@link #startOp(int, int, String)} for your actual security checks, which also
* ensure that the given uid and package name are consistent. This function can just be
* used for a quick check to see if an operation has been disabled for the application,
* as an early reject of some work. This does not modify the time stamp or other data
* about the operation.
* @param op The operation to check. One of the OP_* constants.
* @param uid The user id of the application attempting to perform the operation.
* @param packageName The name of the application attempting to perform the operation.
* @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
* {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
* causing the app to crash).
* @throws SecurityException If the app has been configured to crash on this op.
* @hide
*/
public int checkOp(int op, int uid, String packageName) {
try {
int mode = mService.checkOperation(op, uid, packageName);
if (mode == MODE_ERRORED) {
throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
}
return mode;
} catch (RemoteException e) {
}
return MODE_IGNORED;
}
操作id即op可以在该类中找到静态值定义,android23里面有62种权限,我们需要的是OP_SYSTEM_ALERT_WINDOW=24
知道这些就可以用反射把我们的方法写出了:
/**
* 判断 悬浮窗口权限是否打开
*
* @param context
* @return true 允许 false禁止
*/
public static boolean getAppOps(Context context) {
try {
Object object = context.getSystemService("appops");
if (object == null) {
return false;
}
Class localClass = object.getClass();
Class[] arrayOfClass = new Class[3];
arrayOfClass[0] = Integer.TYPE;
arrayOfClass[1] = Integer.TYPE;
arrayOfClass[2] = String.class;
Method method = localClass.getMethod("checkOp", arrayOfClass);
if (method == null) {
return false;
}
Object[] arrayOfObject1 = new Object[3];
arrayOfObject1[0] = Integer.valueOf(24);
arrayOfObject1[1] = Integer.valueOf(Binder.getCallingUid());
arrayOfObject1[2] = context.getPackageName();
int m = ((Integer) method.invoke(object, arrayOfObject1)).intValue();
return m == AppOpsManager.MODE_ALLOWED;
} catch (Exception ex) {
}
return false;
}
测试在魅族华为小米大部分机型上都是可以的,但这个方法也不能保证正确,一些机型上会返回错误即MODE_ERRORED,就是获取不到权限值,这个方法就返回了false,但实际上悬浮窗是可以使用的。
来源:https://blog.csdn.net/mzm489321926/article/details/50542065
标签:Android,悬浮窗,权限
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Spring Cloud Eureka 服务上下线监控的实现
2022-02-18 21:06:15
Android使用TextView,设置onClick属性无效的解决方法
2022-06-27 11:32:39
C#微信公众号开发之使用MessageHandler简化消息处理流程
2022-04-12 12:12:34
Java面向对象之猜拳游戏
2022-10-29 21:26:45
![](https://img.aspxhome.com/file/2023/8/80208_0s.jpg)
使用Spring Cloud Feign远程调用的方法示例
2021-12-06 10:30:09
数组实现Java 自定义Queue队列及应用操作
2023-11-28 09:11:13
![](https://img.aspxhome.com/file/2023/0/60380_0s.png)
Java实现宠物商店管理
2023-09-14 09:14:13
Nginx启用压缩及开启gzip 压缩的方法
2021-09-20 21:19:25
![](https://img.aspxhome.com/file/2023/8/66628_0s.png)
android实现常驻通知栏遇到的问题及解决办法
2022-10-12 06:06:58
![](https://img.aspxhome.com/file/2023/2/139312_0s.jpg)
java 抽象类的实例详解
2023-06-08 05:52:40
字符串阵列String[]转换为整型阵列Int[]的实例
2021-07-22 08:19:17
![](https://img.aspxhome.com/file/2023/1/116531_0s.jpg)
Android实现银行卡号扫描识别功能
2021-09-05 01:56:50
Java核心编程之文件随机读写类RandomAccessFile详解
2023-11-28 17:40:05
浅谈c#.net中巧用ToString()将日期转成想要的格式
2022-02-02 18:14:07
java控制台打印本月的日历
2023-10-15 22:58:12
![](https://img.aspxhome.com/file/2023/1/58621_0s.jpg)
并发编程之Java内存模型顺序一致性
2023-04-11 08:12:25
![](https://img.aspxhome.com/file/2023/8/132198_0s.png)
unity绘制一条流动的弧线(贝塞尔线)
2022-09-03 18:15:00
![](https://img.aspxhome.com/file/2023/6/129676_0s.jpg)
java Mail邮件接收工具类
2022-04-24 14:17:17
Android应用框架之应用启动过程详解
2023-06-05 02:20:47
mybatis中<choose>标签的用法说明
2023-07-22 19:37:27
![](https://img.aspxhome.com/file/2023/5/132185_0s.png)