Devin Rodriguez Devin Rodriguez - 19 days ago 5
Android Question

Return to app after requesting SYSTEM_ALERT_WINDOW permission

My app requires permission to draw over other apps to work correctly, so at the start of the application I check for permission and, if needed, ask the user to grant it, then start the request via the following code:

Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + activity.getPackageName()));
activity.startActivityForResult(intent, REQUEST_OVERLAY_PERMISSION);


This requires that the user press the back button after enabling permission, but I've noticed that some apps are able to automatically return or go to another activity after the user enables it. How is this accomplished? Is there a service listening in the background that is periodically checking to see if the user has enabled something?

Answer

It appears that there is no way to observe this setting, so there is really no elegant solution for this.

What you can do is just check the setting once per second using a Handler after you send the user to the Settings screen.

You can't truly "go back" programmatically from the Settings screen, so the only option is to re-launch the Activity and clear the previous ones (otherwise it will go back to the Settings screen on back press afterwards).

With the example below, within one second of enabling the setting, it will re-launch MainActivity.

First define the Runnable:

Handler handler = new Handler();
Runnable checkOverlaySetting = new Runnable() {
    @Override
    @TargetApi(23)
    public void run() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return;
        }
        if (Settings.canDrawOverlays(MainActivity.this)) {
            //You have the permission, re-launch MainActivity
            Intent i = new Intent(MainActivity.this, MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(i);
            return;
        }
        handler.postDelayed(this, 1000);
    }
};

Then start the Runnable when you send the user to the Settings screen:

Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
//Add this here:
handler.postDelayed(checkOverlaySetting, 1000);

Note that you should set a timeout or max tries so that it doesn't go on forever if the user does not enable the overlay setting.