Come posso utilizzare AccessibilityService.getWindows () per get un AccessibilityNodeInfo traversabile?

Sto scrivendo un AccessibilityService per Android e, fino al livello API 20, ho utilizzato il metodo AccessibilityEvent.getSource() per get un AccessibilityNodeInfo attraversabile quando viene triggersto l' onAccessibilityEvent(AccessibilityEvent event) . Anche se l' AccessibilityNodeInfo risultante non sempre riflette il contenuto dello schermo, è ancora ansible lavorare con esso.

A partire dal livello API 21, il nuovo AccessibilityService.getWindows() dovrebbe non solo essere in grado di rappresentare meglio la gerarchia delle visualizzazioni (vale a dire rispettando l'sorting Z), ma dovrebbe anche essere in grado di esporre un nodo che include tutte le viste nel metodo di immissione corrente (IME). Vorrei approfittare di questo ma non sono stato in grado di farlo e non so cosa esattamente sto facendo male. Per inciso, non sono stato in grado di trovare informazioni più dettagliate su come farlo, ad exception dei documenti minimi java.

  • Disposizione Relativa: comportmenti diversi su Api <11
  • Come aggiornare il mio ListView dopo la modifica del database?
  • Cattura foto ruotare 90 gradi in cellulare samsung
  • Utilizzo di Android AutoCompleteTextView con ArrayAdapter <Oggetti> invece di ArrayAdapter <Archi>
  • Come get gli album di foto utente di Facebook utilizzando il grafico api?
  • Android Studio ha corrotto file .java dopo l'arresto improprio
  • Ho già fatto quanto segue:

    • Servizio configurato per recuperare il contenuto della window ( android:canRetrieveWindowContent="true" )
    • Aggiunto flagRetrieveInteractiveWindows ai flag di servizio

    Il mio codice è il seguente:

     @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); } } 

    where getNodesFromWindows () esegue le seguenti operazioni:

     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; } 

    dopo di che, updateTargetLeafs() raccoglie tutti i nodes cliccabili, abilitati e visibili in un updateTargetLeafs() separato di AccessibilityNodeInfo ArrayList modo da poter indirizzarli e accedervi a loro volta (vedi sotto). Quando si utilizza AccessibilityEvent.getSource() su API Level 20 e inferiore, la dimensione di questa matrix è sempre vicino al numero di visualizzazioni sullo schermo, ma quando utilizzo AccessibilityService.getWindows() la dimensione è quasi sempre 1 (a volte 0) , ei limiti dell'unico AccessibilityNodeInfo nell'elenco sono sempre al di fuori dello schermo.

    EDIT: Aggiungere il codice per iterare attraverso tutti i nodes i bambini (where mNodes è l'output di 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!"); ... 

    Strano, lo so, ma cosa faccio male?

  • Impostare il text in AccessibilityNodeInfo
  • 'Attributo content descriptore mancante nell'image' nell'XML
  • App Android: come leggere la dimensione del carattere in Impostazioni?
  • Come posso mantenere un gesto di un puntatore quando è triggersto l'esplorazione per contatto?
  • Come fare clic sul button nelle impostazioni utilizzando AccessibilityService?
  • Come sapere se Android TalkBack è attivo?
  • 2 Solutions collect form web for “Come posso utilizzare AccessibilityService.getWindows () per get un AccessibilityNodeInfo traversabile?”

    È ansible accedere al contenuto di Windows utilizzando il getChild() . Nel tuo onAccessibilityEvent(AccessibilityEvent event) puoi fare come segue.

     @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 } } 

    getNodesFromWindows () restituisce solo un elenco di nodes root. Hai bisogno di iterare attraverso i suoi figli per raccogliere tutti i nodes nella window.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.