Displaying popup windows while running in the background?
Asked Answered
H

5

28

I am trying to open an activity from a class that extends Service. I am performing this task when the app is not in foreground/not being used. I can see in the logs that my service class triggered start activity with Intent.FLAG_ACTIVITY_NEW_TASK flag. But the activity does not open. But when the service triggers the same activity when the app is in foreground/being used, the activity opens.

After few searches I found out that I need to manually give the permission "display popup windows while running in the background android" in the other permissions section in the app settings.

The display over other apps permission SYSTEM_ALERT_WINDOW only gives access to "Display popup window".

Other permissions

In the image above, SYSTEM_ALERT_WINDOW will only grant you access to "Display popup window" and this works fine if the app is in foreground/being used but the permission marked in red if granted will give you access to open any activity directly from a class extending Service.

How do I check or ask the user to give "Display popup windows while running in the background" permission? or Is this permission restricted?

I see apps like Whatsapp have this checked by default.

Hydroscope answered 8/1, 2020 at 12:30 Comment(10)
https://mcmap.net/q/487231/-how-to-programmatically-grant-the-quot-draw-over-other-apps-quot-permission-in-android Check this answerBummer
Does this answer your question? How to programmatically grant the "draw over other apps" permission in android?Bummer
Sorry @AswinPAshok, I am using the above solution already, but that is not what I am looking for. Any how thank you so much for the reply. :) I have edited the question with an image for better clarity.Hydroscope
@SidharthMA Did you got any solution for it?Boohoo
Hi @ShayanPourvatan, Sorry to say this, I am still finding a solution!. Do you have any clue?Hydroscope
@SidharthMA No, as I've searched we cannot to change permission in runtime, only solution is show headsUp notification to user and ask him to enable it, but we need another permission to show headsUp notification for those user that we can't permit it unfortunately ( show floating notification )Boohoo
Does Android 10 fix this, removing this weird setting? I noticed that now it's on the docs, that some cases will be excluded for Android 10 : developer.android.com/guide/components/activities/… , but I think it's still turned off by default.Creativity
@SidharthMA interesting question. Is there any solution? I've seen that Facebook auto on this permission.Danuloff
@BhavinChauhan, unfortunately no. But I did check the Facebook settings page and found that this permission was turned ON by default. Dont know how!!Hydroscope
@SidharthMA also I know its default on for white listed all like Uber, Facebook etcDanuloff
D
9

This is common problem in Xiaomi devices for developers,

the solution we have for the moment is to redirect users to other permissions screen and let the users give the permission manually :

if ("xiaomi" == Build.MANUFACTURER.toLowerCase(Locale.ROOT)) {
    val intent = Intent("miui.intent.action.APP_PERM_EDITOR")
    intent.setClassName("com.miui.securitycenter",
            "com.miui.permcenter.permissions.PermissionsEditorActivity")
    intent.putExtra("extra_pkgname", getPackageName())
    startActivity(intent)
}

You can use Settings.canDrawOverlays(this) to test only if the user has given the Display pop-up windows which means the app can draw over the system ui.

The other two permissions can not be verified if the user has given them or not :

  1. Display pop-up windows while running in the background : this one means to allow the app to draw over the system ui while the app is running in the background like services and broadcast
  2. Show on lock screen : this one gives the app the permission to run even when the screen is locked like social apps (whatsApp , Viber , Messnger ...)
Delano answered 4/10, 2020 at 13:22 Comment(2)
See @Kasun Thilina's clever response below to address the issue: "now the problem is you can't check if the user grant the permission or not"Alvaalvan
How to check if user has grant permission for this ?Venom
B
7

Since there is no official way to check the "Display pop-up windows while running in the background" permission, I used a little trick to check the permissions.

Check if the app can draw overlays like below and then if the device is xiaomi navigate the user to the specific settings screen like below.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (!Settings.canDrawOverlays(this)) {
        if ("xiaomi".equals(Build.MANUFACTURER.toLowerCase(Locale.ROOT))) {
            final Intent intent =new Intent("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
            intent.putExtra("extra_pkgname", getPackageName());
            new AlertDialog.Builder(this)
                .setTitle("Please Enable the additional permissions")
                .setMessage("You will not receive notifications while the app is in background if you disable these permissions")
                .setPositiveButton("Go to Settings", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        startActivity(intent);
                    }
                })
                .setIcon(android.R.drawable.ic_dialog_info)
                .setCancelable(false)
                .show();
        } else {
            Intent overlaySettings = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
            startActivityForResult(overlaySettings, OVERLAY_REQUEST_CODE);
        }
    }
}
Biopsy answered 20/11, 2020 at 6:8 Comment(2)
Settings.canDrawOverlays(this) Will this assure Display pop-up windows is given ?Pinette
I am not able to understand this solution. Can you please elaborate it a bit please?Nimrod
C
1

Here is a working way to find out if it's granted (tested on MIUI 14.0.3)

public static final int OP_BACKGROUND_START_ACTIVITY = 10021;

@SuppressWarnings("JavaReflectionMemberAccess")
@TargetApi(19)
public static boolean isBackgroundStartActivityPermissionGranted(Context context) {
    try {
        AppOpsManager mgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        Method m = AppOpsManager.class.getMethod("checkOpNoThrow", int.class, int.class, String.class);
        int result = (int) m.invoke(mgr, OP_BACKGROUND_START_ACTIVITY, android.os.Process.myUid(), context.getPackageName());
        return result == AppOpsManager.MODE_ALLOWED;
    } catch (Exception e) {
        Log.d("Exception", e.toString());
    }
    return true;
}

You can find an even more detailed code here: https://github.com/zoontek/react-native-permissions/issues/412#issuecomment-1590376224

Clan answered 18/1 at 21:37 Comment(1)
Great answer. If you need to check "Show on lock screen" us 10020 instead of 10021.Demythologize
R
0

Try the following code.

 Intent rIntent = context.getPackageManager()
                    .getLaunchIntentForPackage(context.getPackageName() );
            PendingIntent intent = PendingIntent.getActivity(
                    context, 0,
                    rIntent, PendingIntent.FLAG_CANCEL_CURRENT);
            AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            manager.set(AlarmManager.RTC, System.currentTimeMillis(), intent);
            System.exit(2);
Revoke answered 13/1, 2020 at 8:39 Comment(4)
Hi, the solutions works in a way.. but i would prefer with a permission. Thank you :)Hydroscope
Why the need to call "System.exit(2);" , and why 2 as a parameter?Creativity
System.exit() terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination. So exit(0) generally used to indicate successful termination. And other parameters such as 1,2,-1 all indicates unsuccessful termination. There is no difference.Revoke
How to check that permission is already granted or not?Polydeuces
L
0

I manage to work around my project by following this gist https://gist.github.com/0awawa0/65bf88e43159750f596da194ed923522

@ReactMethod()
    public void isMiuiCanDisplayOverlay(Promise ps){
        boolean isXiaomi = XiaomiUtilities.isMIUI();
        boolean isGranted = XiaomiUtilities.isPermissionGranted(reactContext,XiaomiUtilities.OP_BACKGROUND_START_ACTIVITY);
        if(isXiaomi){
            ps.resolve(isGranted);
        }else{
            ps.resolve(true);
        }
    }
    @ReactMethod()
    public void openMiuiDisplayOverlayPermission(Promise ps){
        boolean isXiaomi = XiaomiUtilities.isMIUI();
        try{
            if(isXiaomi){
                XiaomiUtilities.goToMiuiPermissionActivity_V8(reactContext);
                ps.resolve(true);
            }else{
                ps.resolve(false);
            }
        }catch (Exception e){
            String version = XiaomiUtilities.getMiuiVersion();
            Log.d(LOG_TAG,"Cannot open Miui Display Pop-up window while running in background" + version + e.toString());
        }
    }

    

code above I created in react native to bridge to javascript
Location answered 13/6, 2023 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.