title: How can I use AccessibilityService.getWindows() to obtain a traversable AccessibilityNodeInfo?
body: <p>I am writing an <code>AccessibilityService</code> for Android and, up to API level 20, I have been using the <code>AccessibilityEvent.getSource()</code> method to obtain a traversable <code>AccessibilityNodeInfo</code> when <code>onAccessibilityEvent(AccessibilityEvent event)</code> is triggered. Although the resulting <code>AccessibilityNodeInfo</code> does not always reflect the content of the screen, it is still possible to work with it.</p>
  
  <p>Starting on API level 21, the new <code>AccessibilityService.getWindows()</code> 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.</p>
  
  <p>I have already done the following:</p>
  
  <ul>
  <li>Configured service to retrieve window content (<code>android:canRetrieveWindowContent="true"</code>)</li>
  <li>Added <code>flagRetrieveInteractiveWindows</code> to service flags</li>
  </ul>
  
  <p>My code is as follows:</p>
  
  <pre><code>@Override
  public void onAccessibilityEvent(AccessibilityEvent event) {
              ArrayList&lt;AccessibilityNodeInfo&gt; 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);
                  }
  }
  </code></pre>
  
  <p>where getNodesFromWindows() does the following:</p>
  
  <pre><code>private ArrayList&lt;AccessibilityNodeInfo&gt; getNodesFromWindows() {
      List&lt;AccessibilityWindowInfo&gt; windows = getWindows();
      ArrayList&lt;AccessibilityNodeInfo&gt; nodes =
              new ArrayList&lt;AccessibilityNodeInfo&gt;();
      if (windows.size() &gt; 0) {
          for (AccessibilityWindowInfo window : windows) {
              nodes.add(window.getRoot());
          }
      }
      return nodes;
  }
  </code></pre>
  
  <p>after this, <code>updateTargetLeafs()</code> collects all clickable, enabled and visible nodes into a separate <code>AccessibilityNodeInfo</code> <code>ArrayList</code> so I can index and access them at will (see below). When using <code>AccessibilityEvent.getSource()</code> 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 <code>AccessibilityService.getWindows()</code> the size is almost always 1 (sometimes 0), and the bounds of the only <code>AccessibilityNodeInfo</code> in the list are always outside of the screen.</p>
  
  <p>EDIT: Add the code for iterating through all nodes children (where <code>mNodes</code> is the output of <code>getNodesFromWindows()</code>):</p>
  
  <pre><code>        ...
          ArrayList&lt;AccessibilityNodeInfo&gt; theseleafs =
                      new ArrayList&lt;AccessibilityNodeInfo&gt;();
          AccessibilityNodeInfo thisnode;
          Queue&lt;AccessibilityNodeInfo&gt; q =
                  new LinkedList&lt;AccessibilityNodeInfo&gt;();
          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&lt;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!");
          ...
  </code></pre>
  
  <p>Odd, I know, but what am I doing wrong?</p>