6

私はAccessibilityServiceAndroid 用の を書いていますが、API レベル 20 までは、トリガーされたときにAccessibilityEvent.getSource()トラバーサブルを取得するメソッドを使用しています。結果は必ずしも画面の内容を反映しているわけではありませんが、操作は可能です。AccessibilityNodeInfoonAccessibilityEvent(AccessibilityEvent event)AccessibilityNodeInfo

API レベル 21 以降、新しいAccessibilityService.getWindows()はビュー階層をより適切に表現できるようになる (つまり、Z オーダーが尊重される) だけでなく、現在のすべてのビューを含むノードを公開できるようになることも想定されています。入力方法 (IME)。これを利用したいのですが、それができず、何が間違っているのか正確にはわかりません。ちなみに、非常に最小限のJavaドキュメント以外に、これを行う方法に関する詳細な情報を見つけることができませんでした.

私はすでに次のことを行っています:

  • ウィンドウのコンテンツを取得するように構成されたサービス ( android:canRetrieveWindowContent="true")
  • flagRetrieveInteractiveWindowsサービスフラグに追加

私のコードは次のとおりです。

@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() は次のことを行います。

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インデックスを付けてアクセスできるようにします (以下を参照)。API レベル 20 以下で使用する場合AccessibilityEvent.getSource()、この配列のサイズは常に画面上のビューの数に近くなりますが、使用する場合AccessibilityService.getWindows()、サイズはほとんど常に 1 (場合によっては 0) でありAccessibilityNodeInfo、リスト内のみの境界です。常に画面の外にいます。

編集: すべてのノードの子を反復処理するためのコードを追加します (mNodesはの出力です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!");
        ...

奇妙なことですが、何が間違っているのでしょうか?

4

2 に答える 2

5

getChild()メソッドを使用して Windows コンテンツにアクセスできます。あなたonAccessibilityEvent(AccessibilityEvent event)は以下のようにすることができます。

@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
          }
}
于 2015-05-05T03:25:29.873 に答える
0

getNodesFromWindows() はルート ノードのリストのみを返します。ウィンドウ内のすべてのノードを収集するには、その子を反復処理する必要があります。

于 2015-02-23T16:58:09.747 に答える