因此,我是新手,并且一直在玩onAccessibilityEvent并从其他应用程序中读取屏幕上的TextViews,效果很好,但现在我希望能够使用AccessibilityNodeInfo.ACTION_CLICK单击其中的一些。我的问题是,来自其他应用程序的大多数这些TextView都没有打开可点击的控件,但是它们的弹出窗口位于可点击的android.widget.LinearLayoutandroid.widget.FrameLayout中。但是我的代码似乎没有点击它们。有什么建议么?

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

最佳答案

我认为您同意我的意见,问题出在:

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



  当此方法返回“列表”时,乍一看可能会想到
  它返回此字符串中提到的所有节点。实际上,
  扫描字符串并返回包含而不是一部分的所有节点,
  但是整个字符串。


在您的程序中,赋予“ clickScreen”的字符串包含所有视图文本。因此,您是否可以:


每当您与其中一个人碰面时,请点击视图:

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


如果要单击特定视图,则必须事先知道其文本或部分视图(请注意“确定”和“取消”,因为它会关闭屏幕):

child.getText().toString().toLowerCase().contains()("your text");

或将它们全部放入ArrayList中,然后单击您想要的内容:


填充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));
    }
    ...
}

迭代列表,然后单击:

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

10-07 19:27
查看更多