How to handle SYSTEM_ALERT_WINDOW permission not being auto-granted on some pre-Marshmallow devices

后端 未结 5 579
执笔经年
执笔经年 2020-11-30 01:24

I\'ve been getting reports of some Xiaomi devices (e.g. Mi 2, running API level 21) not showing overlays. My app targets API 23.

There are several posts out there r

5条回答
  •  囚心锁ツ
    2020-11-30 02:04

    Checking if you have the drawOverlays permission is safer using this:

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

    Custom ROMs can have altered the OS so that that Settings.canDrawOverlays() is not available. This happened to me with Xiaomi devices and the app crashed.

    Requesting the permission:

    @SuppressLint("InlinedApi")
    public static void requestOverlayDrawPermission(Activity act, int requestCode){
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + act.getPackageName()));
        act.startActivityForResult(intent, requestCode);
    
    }
    

提交回复
热议问题