私はAccessibilityService
Android 用の を書いていますが、API レベル 20 までは、トリガーされたときにAccessibilityEvent.getSource()
トラバーサブルを取得するメソッドを使用しています。結果は必ずしも画面の内容を反映しているわけではありませんが、操作は可能です。AccessibilityNodeInfo
onAccessibilityEvent(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!");
...
奇妙なことですが、何が間違っているのでしょうか?