如何使用AccessibilityService.getWindows()来获取一个遍历AccessibilityNodeInfo? [英] How can I use AccessibilityService.getWindows() to obtain a traversable AccessibilityNodeInfo?
问题描述
我写了 AccessibilityService
Android和,达到API等级20,我已经使用过的 AccessibilityEvent.getSource()
方法来获取遍历 AccessibilityNodeInfo
在 onAccessibilityEvent(AccessibilityEvent事件)
被触发。虽然得到的 AccessibilityNodeInfo
并不总是反映在屏幕的内容,仍然可以用它来工作。
I am writing an AccessibilityService
for Android and, up to API level 20, I have been using the AccessibilityEvent.getSource()
method to obtain a traversable AccessibilityNodeInfo
when onAccessibilityEvent(AccessibilityEvent event)
is triggered. Although the resulting AccessibilityNodeInfo
does not always reflect the content of the screen, it is still possible to work with it.
开始在API级别21,新的 AccessibilityService.getWindows()
应该是不仅能够更好地重复present视图层次结构(例如,Z -ordering尊重),但它也应该能够以暴露,其包括在电流输入方式(IME)的所有视图的节点。我想利用这一点,但我一直没能这样做,我不知道究竟我做错了。顺便说一句,我一直无法找到如何做到这一点,除了在非常小的Java文档的任何更详细的信息。
Starting on API level 21, the new AccessibilityService.getWindows()
is supposed to be not only able to better represent the view hierarchy (i.e., Z-ordering is respected), but it is also supposed to be able to expose a node that includes all views in the current input method (IME). I would like to take advantage of this but I have not been able to do so and I do not know what exactly I am doing wrong. Incidentally, I have been unable to find any more detailed information on how to do this, other than the very minimal java docs.
我已经做了以下内容:
- 配置服务检索窗口含量(
安卓canRetrieveWindowContent =真正的
) - 新增
flagRetrieveInteractiveWindows
来服务标志
- Configured service to retrieve window content (
android:canRetrieveWindowContent="true"
) - Added
flagRetrieveInteractiveWindows
to service flags
我的code是如下:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
ArrayList<AccessibilityNodeInfo> nodes = getNodesFromWindows();
switch (event_type) {
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
//case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
case AccessibilityEvent.TYPE_VIEW_SELECTED:
case AccessibilityEvent.TYPE_VIEW_SCROLLED:
//case AccessibilityEvent.TYPE_VIEW_CLICKED:
updateTargetLeafs(nodes);
}
}
在这里getNodesFromWindows()进行以下操作:
where getNodesFromWindows() does the following:
private ArrayList<AccessibilityNodeInfo> getNodesFromWindows() {
List<AccessibilityWindowInfo> windows = getWindows();
ArrayList<AccessibilityNodeInfo> nodes =
new ArrayList<AccessibilityNodeInfo>();
if (windows.size() > 0) {
for (AccessibilityWindowInfo window : windows) {
nodes.add(window.getRoot());
}
}
return nodes;
}
在此之后, updateTargetLeafs()
收集所有点击,启动和可视节点到一个单独的 AccessibilityNodeInfo
的ArrayList
这样我可以索引和访问他们的意愿(见下文)。当使用 AccessibilityEvent.getSource()
的API等级20及以下,此数组的大小总是接近的屏幕上观看的次数,但是当我使用 AccessibilityService.getWindows()
尺寸几乎总是1(有时是0),唯一的 AccessibilityNodeInfo
列表中的边界总是在屏幕的外部。
after this, updateTargetLeafs()
collects all clickable, enabled and visible nodes into a separate AccessibilityNodeInfo
ArrayList
so I can index and access them at will (see below). When using AccessibilityEvent.getSource()
on API Level 20 and below, the size of this array is always close to the number of views on the screen, but when I use AccessibilityService.getWindows()
the size is almost always 1 (sometimes 0), and the bounds of the only AccessibilityNodeInfo
in the list are always outside of the screen.
编辑:添加code通过所有节点的孩子迭代(其中 mNodes
是 getNodesFromWindows输出()
):
Add the code for iterating through all nodes children (where mNodes
is the output of getNodesFromWindows()
):
...
ArrayList<AccessibilityNodeInfo> theseleafs =
new ArrayList<AccessibilityNodeInfo>();
AccessibilityNodeInfo thisnode;
Queue<AccessibilityNodeInfo> q =
new LinkedList<AccessibilityNodeInfo>();
for (AccessibilityNodeInfo n : mNodes) {
q.add(n);
}
while (!q.isEmpty()) {
thisnode = q.poll();
if (shouldIncludeNode(thisnode)) {
//Add only if it fulfills all requirements!
theseleafs.add(thisnode);
}
for (i=0; i<thisnode.getChildCount(); ++i) {
AccessibilityNodeInfo n = thisnode.getChild(i);
if (n != null) q.add(n); // Add only if not null!
}
};
LogD("MyTag", theseleafs.size() + " leafs in this node!");
...
奇怪,我知道,但我究竟做错了什么?
Odd, I know, but what am I doing wrong?
推荐答案
您可以使用 getChild()
方法的窗口内容访问。
在你的 onAccessibilityEvent(AccessibilityEvent事件)
,你可以像下面的。
You can get access of windows content using getChild()
method.
In your onAccessibilityEvent(AccessibilityEvent event)
you can do like below.
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo mSource = event.getSource();
int child = mSource.getChildCount();
// iterate through all child of parent view
for (int i=0; i<child; i++){
AccessibilityNodeInfo childNodeView = mParent.getChild(i);
// Do something with this window content
}
}
这篇关于如何使用AccessibilityService.getWindows()来获取一个遍历AccessibilityNodeInfo?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!