Starting an activity from an accessibility service doesn't work with Xiaomi

Viewed 794

I have an accessibility service which has to open an activity when some conditions are met.

The code to open the activity is this:

Intent intent = new Intent(WindowChangeDetectingService.this, OpenActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

I've tried many other flags like FLAG_ACTIVITY_BROUGHT_TO_FRONT or FLAG_ACTIVITY_REORDER_TO_FRONT, and set action as: ACTION_PICK_ACTIVITY, but it doesn't start the activity.

I'm using a Xiaomi Mi9T and it doesn't work, but a colleague uses a Huawei and it does work for him, and on the emulator (Pixel phone) it works too. How can I fix this for the Xiaomi devices?

1 Answers

Xiaomi restricts apps from starting activity from the background by default. You'll have to guide users to manually allow it. (Official MIUI announcement: https://www.xiaomi.cn/post/9216439 )

Open this intent and let the user manually allow the permission "start in the background":

    intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");

How to know if the user has already allowed this permission? Here's a piece of code found from the Internet:

    public static boolean hasBackgroundStartPermissionInMIUI(Context context) {
        AppOpsManager ops = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        try {
          // ops.checkOpNoThrow(op, uid, packageName)
          Field field = AppOpsManager.class.getField("OP_BACKGROUND_START_ACTIVITY");
          field.setAccessible(true);
          int opValue = (int) field.get(ops);
          Method method = ops.getClass().getMethod("checkOpNoThrow", int.class, int.class, String.class);
          Integer result = (Integer) method.invoke(ops, opValue, Process.myUid(), context.getPackageName());
          return result == AppOpsManager.MODE_ALLOWED;
        } catch (Exception e) {
          ProductionEnv.throwExceptForDebugging(e);
          return false;
        }
      }

Additionally, for other permissions in the Xiaomi permission manager. Get a Xiaomi phone and query all the constants declared in AppOpsManager. Then replace the declaredFields with the permission you want.

Related