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 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+.
new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION", packageName)
but I have no means to test this.The permission was introduced in Android 6.0 and it can allow an app to be displayed on top of another app, obscuring the lower-level app. In order to use the SYSTEM_ALERT_WINDOW permission, an app has to have explicit, manual approval from the user.
A flutter plugin to show Truecaller like overlay window, over all other apps along with callback events. Android Go or Android 11 & above, this plugin shows notification bubble, in other android versions, it shows an overlay window.
Android Settings ACTION_MANAGE_OVERLAY_PERMISSION Activity Action: Show screen for controlling which apps can draw on top of other apps.
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), 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. 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) 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With