Sidharth MA
Sidharth MA

Reputation: 281

Displaying popup windows while running in the background?

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.

Upvotes: 30

Views: 27548

Answers (5)

Kasun Thilina
Kasun Thilina

Reputation: 1681

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);
        }
    }
}

Upvotes: 7

Daniel
Daniel

Reputation: 37061

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

Upvotes: 2

asdf
asdf

Reputation: 46

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

Upvotes: 2

elhoucine ayoub
elhoucine ayoub

Reputation: 1009

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 ...)

Upvotes: 11

littlebear333
littlebear333

Reputation: 760

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);

Upvotes: 0

Related Questions