使用无障碍服务中的UiAutomation

5
我正在为Android编写无障碍服务,旨在为身体残疾的人提供不同的控制设备的选择,例如使用开关、扫描、头部追踪和其他方法。
目前,我们使用无障碍API(Accessibility API)来执行应用程序界面上的实际操作,基本上是使用AccessibilityNodeInfo.performAction()方法。这在大多数情况下都很好用,但我们发现一些重要的限制:
- 大多数键盘(IME)根本不起作用。我们只在Lollipop(API 22)上成功使用了Google键盘,并不得不使用AccessibilityService.getWindows()。对于低版本的API,我们不得不开发一个特殊的键盘(毫无疑问不是最佳解决方案)。 - 大多数游戏不可访问。它们没有导出AccessibilityNodeInfo树。 - 网页导航不现实(没有滚动等问题)。
一个解决方案是使用不同的API来执行操作,看起来android.app.UiAutomation会适合这个目的。根据文档,“它还允许注入模拟键盘和触摸设备用户交互的任意原始输入事件”,这正是我想要的;尽管我知道UiAutomation旨在用于测试(也许不适合生产质量代码),并且可能在不同的设备上表现不同。我也明白,如果任何应用程序都可以使用此类API,它可能成为安全漏洞。但是,鉴于AccessibilityNodeInfo.performAction()提供了类似的“权限”,允许辅助功能服务使用UiAutomation似乎是合理的。
因此,在我的辅助功能服务中,我尝试了以下操作:
 Instrumentation i = new Instrumentation();
 UiAutomation automation = i.getUiAutomation();

但是getUiAutomation()总是返回null。

在无障碍服务中有没有使用UiAutomation(或类似API)的选项?

顺便说一句:对我们来说,root设备不是一个选择,因此我们无法通过屏幕驱动程序注入事件


1
“这旨在为身体残障人士提供不同的选择来控制设备,例如使用开关、扫描、头部追踪等等。”-- 这听起来更像是在自定义硬件上运行的定制ROM,而不是在应用程序层面尝试实现。 - CommonsWare
希望“关键”是为身体残疾人提供可靠的“不同的选择,以控制设备,例如使用开关、扫描、头部跟踪和其他方式”。正如您已经发现的那样,Android 设备各不相同。您想要支持的交互越复杂,这些差异就会越影响解决方案的可靠性。更糟糕的是,您将不再控制更新,因此可靠性可能会在一夜之间发生变化而无法控制。这甚至假定您想要的是可能的(据我所知,它是不可能的)。 - CommonsWare
“我错了吗?”-- 不,就API而言是正确的。 “你能解释一下在这个特定情况下缺乏可靠性的原因吗?”-- 你假设UiAutomation在所有设备和所有应用程序上的行为都是相同的。除此之外,你还假设UiAutomation是为生产使用而设计的,而不是其声明的用途(“开发UI测试自动化工具和库”)。据我所知,这在仪器测试之外是不可用的。 - CommonsWare
你找到了任何解决方案吗?我也面临着类似的需求。 - Zain Ali
目前还没有,但一个很有前途的选择是使用ADB接口注入事件。我尝试了“Remote ADB Shell”,并成功地从同一设备注入了事件。您需要启用USB调试,将设备插入计算机,通过TCP IP启用ADB(adb tcpip 5555),然后就可以连接到localhost:5555并注入这些事件。AdbLib库允许从应用程序通过adb接口进行通信。 - Cesar Mauri
显示剩余4条评论
1个回答

1
我回答自己的问题。
自从 Nougat(API 24)以来,以编程方式在其他应用程序上执行操作的方法是使用无障碍服务和 AccessibilityService#dispatchGesture 方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接