在AccessibilityService中遍历AccessibilityNodeInfos

时间:2017-09-19 11:41:57

标签: android accessibility accessibilityservice android-accessibility

我目前使用getRootInActiveWindow()检索活动窗口的根节点。之后,我执行广度优先搜索以获取所有节点的列表。

我的问题: 如何遍历此节点列表以获取焦点顺序?此列表是否已根据节点的焦点顺序排序?是否有不同的方法来检索焦点顺序?

提前致谢。

1 个答案:

答案 0 :(得分:2)

最终,没有。你不能,而且关于这一点的可访问性api文档是非常误导的。

有人可能认为" focusSearch(int direction)" AccessibilityNodeInfo的功能将是你要走的路。但是,最终它被打破了,如果你回到Android Accessibility API的内部,你最终会找到一个记录如下的函数:

  

搜索指定方向上可以获取输入焦点的最近视图。

COOL,我们想要什么?稍等一下。该函数调用函数

AccessibilityInteractionClient.getInstance().focusSearch(mConnectionId, mWindowId, mSourceNodeId, direction);

此功能记录如下:

  

查找可访问性{@link android.view.accessibility.AccessibilityNodeInfo}。搜索在指定了id的窗口中执行,并从指定了可访问性ID的节点开始。

令人失望的是,您还会发现此功能不能完成这些工作(定向焦点搜索或方向可访问性焦点搜索)。

最终,当TalkBack中的元素由于元素的焦点而获得可访问性焦点时,它实际上响应来自OS的实际焦点事件而不是任何TalkBack正在对输入焦点排序进行的计算。

为了做到这一点,你基本上必须从操作系统实现整个逻辑,用于Tab Ordering你自己,系统本身必须做的信息较少,因为系统有真正的android.widget.View个对象要处理使用,而不是信息有限的假AccessibilityNodeInfo个对象。任何你可以做到这一点的方式都会非常脆弱,并且不能保证与系统实际做的一致。

您倾向于尝试广泛的首次遍历"输入可调焦的" (focusable)的AccessibilityNodeInfo属性是一个非常合理的解决方案。问题是,真正的系统Tab Ordering将成为其中的一个子集,它会忽略不同窗口上存在的元素之类的东西。

说真的,打开TalkBack设置屏幕,打开TalkBack,连接硬件键盘,疯狂选项卡和切换标签键,并惊叹于如何将重点放在"设置和#34;按钮。您的遍历功能会出错,因为"设置"按钮是focusable但不知何故,你不能把焦点放在那里。之所以要挖掘一些严重的AOSP废话,我会省略,不,我不确定AccessibilityServices是否可以获得阻止这个角落出现在理论算法中的信息。

总而言之,广度优先遍历在理论上可以起作用,但是会有大量的极端情况,并且我不确定AccessibleServices是否可以正确处理每个角落案例的信息。另外,值得注意的是,由于这个特殊问题,如果您希望解决方案在4.4,5.0和7.0+设备上正确无误,那么对于不同的操作系统版本,您必须对此计算有不同的变体。 YEP,那些角落的情况会有所不同! (队列邪恶的笑声)。

我诚实的推荐......放弃。