从无障碍服务启动活动不适用于小米

Posted

技术标签:

【中文标题】从无障碍服务启动活动不适用于小米【英文标题】:Starting an activity from an accessibility service doesn't work with Xiaomi 【发布时间】:2021-07-18 13:56:36 【问题描述】:

我有一个无障碍服务,它必须在满足某些条件时打开一个活动。

打开活动的代码是这样的:

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

我尝试了许多其他标志,例如 FLAG_ACTIVITY_BROUGHT_TO_FRONTFLAG_ACTIVITY_REORDER_TO_FRONT,并将操作设置为:ACTION_PICK_ACTIVITY,但它不会启动活动。

我用的是小米9T,不行,同事用的是华为,对他好用,在模拟器(Pixel手机)上也好用。如何为小米设备解决此问题?

【问题讨论】:

【参考方案1】:

小米通过以下方式限制应用从后台启动活动 默认。您必须引导用户手动允许它。 (官方的 MIUI公告:https://www.xiaomi.cn/post/9216439)

打开这个intent,让用户手动允许“后台启动”的权限:

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

如何知道用户是否已经允许了这个权限?这里是 从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;
        
      

另外,小米权限管理器中的其他权限。拿到小米手机,查询AppOpsManager中声明的所有常量。然后用你想要的权限替换declaredFields

【讨论】:

谢谢!关于数字 2,在您链接我的同一页面中,它说 AccessibilityService 是一个例外,它允许从后台启动活动,所以我想不是这样。我会尝试第一个,但看起来很有希望,非常感谢! @Stasky 哎呀,我没有仔细阅读这个问题。我正在考虑从正常服务开始活动,因为这正是我去年面临的问题,我花了一段时间才弄清楚。是的,AccessibilityService 是 SDK29 中引入的新限制的例外。我已经修改了答案,以防止它误导其他发现此问题的人。 抱歉一段时间回来,我直到最近才能够处理它。我无法工作,它说我应该在清单中声明"com.miui.securitycenter""com.miui.permcenter.permissions.AppPermissionsEditorActivity",但这些不是我的活动。 @Stasky,它不需要是你的活动,你只需要在清单中声明它。你误解了这个问题,请参阅https://developer.android.com/guide/topics/manifest/queries-element。将此添加到清单<queries> <package android:name="com.miui.securitycenter" /> </queries>。并使用resolveActivityInfo() 检查活动是否存在并“exported = true”,如果结果为是,则您可以毫无问题地打开该活动。 我已将以下内容添加到清单中:xml <queries> <package android:name="com.miui.securitycenter" /> </queries> 而此代码:java Intent intent = new Intent(); intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity"); ActivityInfo activityInfo = intent.resolveActivityInfo(getPackageManager(), 0); startActivity(intent); activityInfonull,但我在小米上使用它,所以应该存在,并且logcat 错误仍在询问是否在清单中声明了活动。

以上是关于从无障碍服务启动活动不适用于小米的主要内容,如果未能解决你的问题,请参考以下文章

Passport.js Google 策略不适用于 React 应用程序

有没有办法让活动与启动活动的服务进行通信?

从服务启动活动

在另一个活动中停止从另一个服务启动的服务?

如何在android Q os中从后台服务启动活动,而不从开发人员选项的设置中单击“允许后台活动启动”?

无法从服务启动活动