【问题标题】:How to check permission SYSTEM_ALERT_WINDOW is granted on Android Lollipop?如何检查在 Android Lollipop 上授予的权限 SYSTEM_ALERT_WINDOW?
【发布时间】:2015-10-28 03:30:21
【问题描述】:

请注意,我说的是 Android Lollipop。对于 android 6.0,我们可以使用方法 canDrawOverlays() 来检查 SYSTEM_ALERT_WINDOW 是否被授予。

使用 Android Lollipop,几乎所有设备都会默认授予此权限。但是在小米,魅族的某些设备上..它是不被允许的。用户需要进入应用信息才能允许。

我们如何以编程方式检查它以警告用户?

【问题讨论】:

    标签: android permissions android-5.0-lollipop grant


    【解决方案1】:

    在 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

    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);
    }
    

    【讨论】:

    • 非常感谢!我试试看!
    • 我在哪里可以获得 OP_SYSTEM_ALERT_WINDOW?什么是uid?
    • 我找不到ReflectUtils。我在哪里可以买到?
    • 你用两个参数调用 checkOp 并在下面用四个参数定义它。!!!我的意思是...如果您要复制/粘贴,至少快速查看一下您要复制/粘贴的内容...
    • 仍然没有答案从哪里获取 OP_SYSTEM_ALERT_WINDOW 或 getBaseTypeClass?
    【解决方案2】:

    反思是有风险的,因为您认为事情是理所当然的……而且在未来的 Android 版本中事情可能会发生变化。以下方法仅在正确方法失败时才使用反射。

    @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;  }
    
     }
    

    【讨论】:

    • 在小米note3中获取AppOpsManager.MODE_IGNORED或值为1。需要进一步的建议。
    • 那你没有权限....请求它: Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + act.getPackageName())) ; startActivityForResult(intent, requestCode);
    • 返回 android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.settings.action.MANAGE_OVERLAY_PERMISSION dat=package:com.findmeout.android }
    • 您使用什么设备进行测试?我在我的任何设备或模拟器(包括小米红米 3 手机)中使用它都没有出错
    • 为什么需要反思? checkOp 来自 API 19,然后无论如何您都返回 true...
    猜你喜欢
    • 1970-01-01
    • 2017-03-01
    • 2017-11-16
    • 2015-08-13
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多