26

How can I programmatically grant the permission in Settings -> Apps -> Draw over other apps in Android? I want to use system alert window but unable to in Android Marshmallow without forcing the user to go through the Settings app and grant the permission first.

scorpiodawg
  • 5,612
  • 3
  • 42
  • 62
Anil Ranga
  • 337
  • 1
  • 3
  • 6

4 Answers4

43

You can check and ask for overlay permission to draw over other apps using this

if (!Settings.canDrawOverlays(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 0);
}
Shashank Udupa
  • 2,173
  • 1
  • 19
  • 26
  • sir this code generate a system window for on or of the overlay permission – Anil Ranga Nov 01 '16 at 07:06
  • 1
    I want it programmatically on no need to user control – Anil Ranga Nov 01 '16 at 07:08
  • 3
    This code checks if your app has overlay permission. If it doesn't it redirects the user to Settings>Apps>draw over apps page to let the user grant permission. There is no way you can programatically grant yourself permission from Android Marasmellow. – Shashank Udupa Nov 01 '16 at 07:10
  • 2
    I wouldn't be so sure about saying there is way to do this. There is an app called XOutOf10 that enables this permission without user interaction. – portfoliobuilder Nov 04 '17 at 20:58
  • 3
    If you checkout the description in their play store it says "Android 6.0+ Users: In your first run, please make sure you "permit drawing over apps"." which the user manually has to enable. It was possible before marshmallow, but no way after – Shashank Udupa Nov 05 '17 at 03:00
  • 1
    "Every app that requests the SYSTEM_ALERT_WINDOW permission and that is installed through the Play Store (version 6.0.5 or higher is required), will have granted the permission automatically." – Curious Mind Nov 16 '18 at 12:53
  • @CuriousMind No, it didn't happen for me. I have tried uploading to playstore with and with protectionLevel but still the user has to enable it manually. Idk how facebook messenger is doing it by default – Kzaf Jan 31 '20 at 12:38
20
if (!Settings.canDrawOverlays(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, 
    Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 0);
}
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
sumit baflipara
  • 209
  • 3
  • 4
10

Here's the code for automatic granting the SYSTEM_ALERT_WINDOW permission to the package. To run this code, your Android application must be system (signed by platform keys).

This method is based on the following Android source code files: AppOpsManager.java and DrawOverlayDetails.java, see the method DrawOverlayDetails.setCanDrawOverlay(boolean newState).

@TargetApi(Build.VERSION_CODES.KITKAT)
public static void autoSetOverlayPermission(Context context, String packageName) {
    PackageManager packageManager = context.getPackageManager();
    int uid = 0;
    try {
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
        uid = applicationInfo.uid;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return;
    }

    AppOpsManager appOpsManager = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
    final int OP_SYSTEM_ALERT_WINDOW = 24;
    try {
        Class clazz = AppOpsManager.class;
        Method method = clazz.getDeclaredMethod("setMode", int.class, int.class, String.class, int.class);
        method.invoke(appOpsManager, OP_SYSTEM_ALERT_WINDOW, uid, packageName, AppOpsManager.MODE_ALLOWED);
        Log.d(Const.LOG_TAG, "Overlay permission granted to " + packageName);
    } catch (Exception e) {
        Log.e(Const.LOG_TAG, Log.getStackTraceString(e));
    }
}

}

The code has been tested in Headwind MDM project, it successfully grants "Draw over other apps" permission without any user consent to the Headwind Remote application (disclaimer: I'm the project owner of Headwind MDM and Headwind Remote), when Headwind MDM application is signed by platform keys. The code has been tested on Android 10 (LineageOS 17).

vmayorow
  • 630
  • 5
  • 15
  • Hi. I have tried your code but I have this exception: Caused by: java.lang.SecurityException: uid 10182 does not have android.permission.UPDATE_APP_OPS_STATS. My app is DeviceOwer... it is not enough? – Alessandro Caliaro Dec 14 '21 at 10:53
  • 2
    Unfortunately Device Owner is not enough to run this code. You need to sign your app by platform keys and use shared user android.uid.system. – vmayorow Dec 15 '21 at 06:20
  • Can an app signed by platform keys use this code to grant others app permission? (Not itself). – Yeung Feb 21 '22 at 07:33
  • I think this code can also be used to grant the permission to other apps (not tested though). Just replace the packageName with the package ID of the app requiring the permission. – vmayorow Feb 22 '22 at 08:12
1

Check this question and the answer:

SYSTEM_ALERT_WINDOW - How to get this permission automatically on Android 6.0 and targetSdkVersion 23

"Every app that requests the SYSTEM_ALERT_WINDOW permission and that is installed through the Play Store (version 6.0.5 or higher is required), will have granted the permission automatically."

Curious Mind
  • 659
  • 10
  • 26
  • 2
    No, it didn't happen for me. I have tried uploading to playstore with and with protectionLevel but still the user has to enable it manually. Idk how facebook messenger is doing it by default – Kzaf Jan 31 '20 at 12:38
  • And you are installing it through the play store? – Curious Mind Feb 03 '20 at 17:09
  • 1
    Yes, please have a look on this answer: https://stackoverflow.com/a/60005258/4720433 – Kzaf Feb 06 '20 at 10:24