[英]How to check permission SYSTEM_ALERT_WINDOW is granted on Android Lollipop?
Note that I'm talking about Android Lollipop . 请注意,我在谈论Android Lollipop 。 For android 6.0 we can use method
canDrawOverlays()
to check that SYSTEM_ALERT_WINDOW
is granted or not. 对于android 6.0,我们可以使用方法
canDrawOverlays()
来检查是否授予了SYSTEM_ALERT_WINDOW
。
With Android Lollipop, almost devices grant this permission by default. 使用Android Lollipop,几乎设备默认授予此权限。 But on some devices of Xiaomi, Meizu.. it is not granted.
但是在小米,魅族的一些设备上......它没有被授予。 Users need to go to the App info to allow it.
用户需要转到应用信息以允许它。
How can we check it programmatically to warn users? 我们如何以编程方式检查它以警告用户?
in MIUI use 在MIUI使用
public static boolean isMiuiFloatWindowOpAllowed(@NonNull Context context) {
final int version = Build.VERSION.SDK_INT;
if (version >= 19) {
return checkOp(context, OP_SYSTEM_ALERT_WINDOW); //See AppOpsManager.OP_SYSTEM_ALERT_WINDOW=24 /*@hide/
} else {
return (context.getApplicationInfo().flags & 1<<27) == 1;
}
}
public static boolean checkOp(Context context, int op, String packageName, int uid) {
final int version = Build.VERSION.SDK_INT;
if (version >= 19) {
AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
try {
return (AppOpsManager.MODE_ALLOWED == (Integer) ReflectUtils.invokeMethod(manager, "checkOp", op, uid, packageName));
} catch (Exception e) {
e.printStackTrace();
}
} else {
Flog.e("Below API 19 cannot invoke!");
}
return false;
}
ReflectUtils.java
ReflectUtils.java
public static Object invokeMethod(@NonNull Object receiver, String methodName, Object... methodArgs) throws Exception {
Class<?>[] argsClass = null;
if (methodArgs != null && methodArgs.length != 0) {
int length = methodArgs.length;
argsClass = new Class[length];
for (int i=0; i<length; i++) {
argsClass[i] = getBaseTypeClass(methodArgs[i].getClass());
}
}
Method method = receiver.getClass().getMethod(methodName, argsClass);
return method.invoke(receiver, methodArgs);
}
Reflection is risky because you take things for granted...and things can change in future versions of Android. 反思是冒险的,因为你认为事情是理所当然的......在未来的Android版本中,事情会发生变化。 The following method only uses reflection if the proper way fails.
如果正确的方法失败,以下方法仅使用反射。
@SuppressLint("NewApi")
public static boolean canDrawOverlayViews(Context con){
if(Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP)
return true;
try {
return Settings.canDrawOverlays(con);
}
catch(NoSuchMethodError e){
return canDrawOverlaysUsingReflection(con);
}
}
public static boolean canDrawOverlaysUsingReflection(Context context) {
try {
AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
Class clazz = AppOpsManager.class;
Method dispatchMethod = clazz.getMethod("checkOp", new Class[] { int.class, int.class, String.class });
//AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
int mode = (Integer) dispatchMethod.invoke(manager, new Object[] { 24, Binder.getCallingUid(), context.getApplicationContext().getPackageName() });
return AppOpsManager.MODE_ALLOWED == mode;
} catch (Exception e) { return false; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.