AccessibilityNodeInfo в getRootInActiveWindow: выполнить щелчок не удается, Rect() не содержит координаты X, Y

Я пытаюсь выполнить щелчок, используя следующий код, но здесь говорит, что существуют некоторые ограничения, и я вижу это в своих тестах.

Но кажется, что эта ошибка вызвана тем, что Rect() не содержит координаты X, Y, почему каждый раз, когда я нажимаю в месте, где не поддерживается (вероятно, какое-то ограничение, как было сказано на файл readme на примере) выполняется эта строка в подпрограмме findSmallestNodeAtPoint():

if (!bounds.contains(x, y)) {
      System.out.println("ERROR DETECTED!!! :::::: NOT bounds.contains(x, y) :::::::");
      return null;
   }

Здесь в этом вопросе также упоминается этот пример Github, и мне был дан ответ с примером кода, работающим на 100% (проверено) с Android Nougat+ (api 24 и выше), но в моем случае мне нужно исправить это код ниже для моего приложения также поддерживает выполнение кликов в предыдущих версиях Android.

Затем, уже зная, где этот код дает сбой, я хочу знать, что можно сделать, связанное с:

!bounds.contains(x, y)

Основная часть кода:

private static void logNodeHierachy(AccessibilityNodeInfo nodeInfo, int depth) {
    Rect bounds = new Rect();
    nodeInfo.getBoundsInScreen(bounds);

    StringBuilder sb = new StringBuilder();
    if (depth > 0) {
        for (int i=0; i<depth; i++) {
            sb.append("  ");
        }
        sb.append("\u2514 ");
    }
    sb.append(nodeInfo.getClassName());
    sb.append(" (" + nodeInfo.getChildCount() +  ")");
    sb.append(" " + bounds.toString());
    if (nodeInfo.getText() != null) {
        sb.append(" - \"" + nodeInfo.getText() + "\"");
    }
    System.out.println(sb.toString());

    for (int i=0; i<nodeInfo.getChildCount(); i++) {
        AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
        if (childNode != null) {
            logNodeHierachy(childNode, depth + 1);
        }
    }
}

private static AccessibilityNodeInfo findSmallestNodeAtPoint(AccessibilityNodeInfo sourceNode, int x, int y) {
    Rect bounds = new Rect();
    sourceNode.getBoundsInScreen(bounds);

    if (!bounds.contains(x, y)) {
        System.out.println(":::::: NOT bounds.contains(x, y) :::::::");
        return null;
    }

    for (int i=0; i<sourceNode.getChildCount(); i++) {
        AccessibilityNodeInfo nearestSmaller = findSmallestNodeAtPoint(sourceNode.getChild(i), x, y);
        if (nearestSmaller != null) {
            return nearestSmaller;
        }
    }
    return sourceNode;
}

public void click(int x, int y) {
    System.out.println(String.format("Click [%d, %d]", x, y));
    AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
    if (nodeInfo == null) return;
    AccessibilityNodeInfo nearestNodeToMouse = findSmallestNodeAtPoint(nodeInfo, x, y);
    if (nearestNodeToMouse != null) {
        logNodeHierachy(nearestNodeToMouse, 0);
        nearestNodeToMouse.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    }
    nodeInfo.recycle();
}

person Community    schedule 26.08.2018    source источник


Ответы (1)


Хорошо, я отвечаю на свой вопрос уже сейчас, что эксперты в AccessibilityService думают, что я создаю вредоносное ПО и не хочу помогать таким людям.


По-видимому, кажется, что невозможно избежать использования Rect() и getBoundsInScreen() на основе этого ответа.

Также я нашел другой похожий код, ссылка:

public void click(int x, int y) {

    clickAtPosition(x, y, getRootInActiveWindow());
}

public static void clickAtPosition(int x, int y, AccessibilityNodeInfo node) {
    if (node == null) return;

    if (node.getChildCount() == 0) {
        Rect buttonRect = new Rect();
        node.getBoundsInScreen(buttonRect);
        if (buttonRect.contains(x, y)) {
            // Maybe we need to think if a large view covers item?
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            System.out.println("1º - Node Information: " + node.toString());
        }
    } else {
        Rect buttonRect = new Rect();
        node.getBoundsInScreen(buttonRect);
        if (buttonRect.contains(x, y)) {
            // Maybe we need to think if a large view covers item?
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            System.out.println("2º - Node Information: " + node.toString());
        }
        for (int i = 0; i < node.getChildCount(); i++) {
            clickAtPosition(x, y, node.getChild(i));
        }
    }
}

а также иметь проблемы. Но это лучше, чем код, связанный с вопросом выше: D.

В моих тестах только не удалось выполнить нажатие на виртуальной клавиатуре Android.

person Community    schedule 02.09.2018