辅助功能服务:获取可以立即与之交互的视图(与“语音访问”相同)?

时间:2019-06-12 13:45:35

标签: android accessibility accessibilityservice android-accessibility accessibility-api

目标是获取可以与即时进行交互的视图(可以立即单击 进行操作)。如果该视图通常可见且可单击,但已被另一个视图/菜单/侧面板悬停,则应将其省略。

Voice Access执行此操作。而且似乎使用了Accessibility API。

完美的例子是Google地图的底部菜单。展开后,下方的“沿路线搜索”按钮仍然可见,但应用程序未突出显示它们。


那我们有什么呢?

  • AccessibilityEvent个信息流。最有用的是 AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,以便在发生事件时通知我们。
  • 使用getSource(),我们可以获取触发事件的AccessibilityNodeInfo实例。 或者,我们可以使用AccessibilityService.getRootInActiveWindow()获得窗口的根。有了它,我们就可以遍历应用程序内的整个层次结构。
  • AccessibilityNodeInfo未提供有关视图的z顺序的任何信息,因此无法了解上方和下方的内容。
  • 底部菜单位于同一窗口中(不是模式窗口)。
  • 如果在展开底部菜单时尝试单击“沿路线搜索”按钮,则底部菜单会折叠。因此,您实际上无法单击它,它在菜单下面。
  • 我已经浏览了AccessibilityNodeInfo的所有参数,例如isVisibleToUser()isClickable()isContextClickable()isSelected(),{{1} },isFocusable()isFocused()和收起/展开底部菜单时,按钮具有相同的参数。它对用户可见,可聚焦和可单击。

  • 我研究了隐藏的API,没有发现任何有用的东西。

我缺少什么?


enter image description here

2 个答案:

答案 0 :(得分:1)

关键点在于,在AccessibilityService.onAccessibilityEvent()中,树层次结构不是最终的。要获取当前可交互的视图,应延迟调用AccessibilityService.getRootInActiveWindow()

答案 1 :(得分:1)

AccessibilityNodeInfo#getDrawingOrder()可能会帮助您。请注意,您需要遍历树来确定什么之上。

仍然存在带有透明视图的极端情况,这会给您带来麻烦,但是应该可以让您95%地解决问题。对于这种情况,我们正在寻求更好的答案。