Question: 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](http://forum.xda-developers.com/xiaomi-mi-3/help/link-bubble-playing-nice-t2857607) [posts](http://en.miui.com/thread-30931-1-1.html) out there regarding this. It seems that MIUI devices do not enable this permission at install time (unlike other pre-Marshmallow devices).

Unfortunately, `Settings.canDrawOverlays()` only works on Android 23+.

1. What is the correct way to check whether this permission has not yet been enabled pre-Marshmallow?
2. Is there an Intent to take the user to the relevant MUIU settings page? Maybe: `new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION", packageName)` but I have no means to test this.

Answer: 
1) on pre-API 23, the permission is already given, because the user granted it upon install.

EDIT: it seems there is a bug on Android 6 (that will [**get fixed on 6.0.1**](https://code.google.com/p/android/issues/detail?id=196597)), that if the user has denied this permission , the app will crash with SecurityException. No idea how Google fixed it though.

2) This way:

```
public static void requestSystemAlertPermission(Activity context, Fragment fragment, int requestCode) {
    if (VERSION.SDK_INT < VERSION_CODES.M)
        return;
    final String packageName = context == null ? fragment.getActivity().getPackageName() : context.getPackageName();
    final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + packageName));
    if (fragment != null)
        fragment.startActivityForResult(intent, requestCode);
    else
        context.startActivityForResult(intent, requestCode);
}

```

Then, in the onActivityResult, you can check if the permission is given or not, as such:

```
@TargetApi(VERSION_CODES.M)
public static boolean isSystemAlertPermissionGranted(Context context) {
    final boolean result = VERSION.SDK_INT < VERSION_CODES.M || Settings.canDrawOverlays(context);
    return result;
}

```

---

EDIT: for the time being, if you publish an app to the Play Store, your app will be auto-granted with this permission. You can read about it [**here**](https://commonsware.com/blog/2016/03/24/system-alert-window-now-more-hidden-than-ever.html). When I asked about it, I thought it was a part of Android itself, as I thought all we need is to target a high enough value for targetSdkVersion. What Google wrote to me ([**here**](https://code.google.com/p/android/issues/detail?id=222195)) is that they wanted to avoid issues on popular apps. 

I suggest handling this permission correctly even if you will get it auto-granted.
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);

}

```