如何使用AccessibilityService.getWindows()来获取一个遍历AccessibilityNodeInfo? [英] How can I use AccessibilityService.getWindows() to obtain a traversable AccessibilityNodeInfo?

查看:11282
本文介绍了如何使用AccessibilityService.getWindows()来获取一个遍历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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆