2017-08-06 1 views
1

は、だから私は新しい午前onAccessibilityEventで遊んや他のアプリからの画面上にあるTextViewsを読んでいる作業とそれは素晴らしい取り組んでいるが、今私はいくつかをクリックしてAccessibilityNodeInfo.ACTION_CLICKを使用することができるようにしたくありませんこれらの。私の問題は、他のアプリからのTextViewのほとんどがクリック可能になっていませんが、クリック可能なandroid.widget.LinearLayoutまたはandroid.widget.FrameLayoutのポップアップが表示されています。しかし、私のコードはそれらをクリックしていないようです。助言がありますか?AccessibilityNodeInfo.ACTION_CLICK

私はあなたは問題がであることを私と一緒に同意すると思います
public class AutoService extends AccessibilityService 
{ 
      @TargetApi(16) 
      @Override 
      public void onAccessibilityEvent(AccessibilityEvent event) 
      { 
       AccessibilityNodeInfo source = event.getSource(); 
       myAdapter.processEvent(source); 
      } 
} 

public class myAdapter 
{ 
    public static void processEvent(final AccessibilityNodeInfo source) 
    { 
     final StringBuilder sb = new StringBuilder(); 
     processSubEvent(source, 0, sb); 
     final String string = sb.toString(); 

     if (string == null) 
     { 
      return; 
     } 

     clickScreen(source, string.toLowerCase()); 
    } 

private static void processSubEvent(final AccessibilityNodeInfo source, final int n, final StringBuilder sb) { 
    for (int i = 0; i < n; ++i) { 
     sb.append("\t"); 
    } 

    if (source != null) 
    { 
     sb.append(source.getText()); 
     sb.append("\n"); 
     final int childCount = source.getChildCount(); 

     for (int i = 0; i < childCount; i++) 
     { 
      AccessibilityNodeInfo child = source.getChild(i); 
      processSubEvent(child, n + 1, sb); 

      if (child != null) 
      { 
       child.recycle(); 
      } 
     } 
    } 
} 

private static void clickScreen(final AccessibilityNodeInfo source, final String text) 
{ 
    List<AccessibilityNodeInfo> list = source.findAccessibilityNodeInfosByText(text); 

    for (final AccessibilityNodeInfo node : list) 
    { 
     node.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
    } 
} 
} 

答えて

1

:このメソッドは、「リスト」を返し、それはすべて返し ことを一目見ただけで心に来るかもしれないと

List<AccessibilityNodeInfo> list = source.findAccessibilityNodeInfosByText(text); 

この文字列で述べたノード。実際には、 は文字列をスキャンし、部分ではなく を含むすべてのノードを返しますが、文字列全体を返します。

プログラムでは、「clickScreen」に与えられた文字列には、すべてのビューのテキストがまとめられています。だから、あなたができるかどうか:

  • クリックしてそれらのいずれかで会うたびビュー:

    if(child.isClickable()){ 
        child.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
    } 
    

    、あなたが特定のビューをクリックしたい場合、あなたはそのテキストまたはの一部を知っている必要がありますそれ事前に(それは、画面を閉じているため、「OK」に注意を払うと、「キャンセル」):

    child.getText().toString().toLowerCase().contains()("your text"); 
    
  • かのArrayListにそれらのすべてを入れて、後で何をしたいクリックします。

    リストを反復処理し、クリックし

    //create new ArrayList 
    public ArrayList<AccessibilityNodeInfo> clickableViews = new ArrayList<>(); 
    
    private static void processSubEvent(final AccessibilityNodeInfo source, final int n, final StringBuilder sb) { 
        ... 
    if (child != null) 
    { 
        //fill the ArrayList with clickable views(make sure to put the origin reference because you will recycle child later) 
        if(child.isClickable()) { 
         clickableViews.add(source.getChild(i)); 
        } 
        ... 
    } 
    
  • :ArrayListのを埋めるために

    1. for (AccessibilityNodeInfo view : clickableViews) { 
          //We only want to click one view per function call! Clicking multiple 
          //views in rapid succession is error prone and functionally ambiguous 
          //meaning it might work in some use cases, and throw exceptions in others. 
          if(view.performAction(AccessibilityNodeInfo.ACTION_CLICK)) break; 
      } 
      
+0

私はArrayListに新しいです、どのように私はクリック可能に格納しますそのリスト内のノードを削除し、後でそれを呼び戻しますか? – Jayce

+0

@Jayce私は答えを変更し、見て: 'if(answer.isHelpfull()){ answer.accept(true); } else { answer.addComment( "あなたのお問い合わせ"); } ' – FarBen

+1

clickableのリストを反復してクリックするのは大まかなアイデアです。おそらく、この関数の呼び出しごとに1つだけクリックするべきです。連続したボタンを数ミリ秒間隔でクリックするのは悪い考えです。最初のそのような要素がクリックされた後でスクリーンコンテンツを無効にして、他のノードを無意味にクリックするようにするのは、よくあることです。そうでなければ、この答えは完璧です。この問題が解決されれば、アップアップします。 – ChrisCM