web-dev-qa-db-fra.com

Comment puis-je simuler de manière fiable des événements tactiles sur Android sans root (comme Automate et Tasker)?

Comment puis-je simuler de manière fiable des événements tactiles sur Android (sans root) à partir de Java en dehors de mon application qui fonctionne en tant que service d'arrière-plan?

Bien que cette question ait déjà été posée, la plupart des réponses utilisent ADB . (comme Comment simuler des événements tactiles sur Android appareil? )

https://github.com/chetbox/Android-mouse-cursor offre une bonne solution en utilisant l'accessibilité, mais n'est pas très fiable car toutes les vues n'y répondent pas, et les jeux ne répondent pas du tout du tout du temps.

private void click() {
  AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
  if (nodeInfo == null) return;

  AccessibilityNodeInfo nearestNodeToMouse = findSmallestNodeAtPoint(nodeInfo, cursorLayout.x, cursorLayout.y + 50);

  if (nearestNodeToMouse != null) {
    logNodeHierachy(nearestNodeToMouse, 0);
    nearestNodeToMouse.performAction(AccessibilityNodeInfo.ACTION_CLICK);
  }

  nodeInfo.recycle();
}

Il s'agit du code actuel utilisé par https://github.com/chetbox/Android-mouse-cursor .

La version Android est 8.0, stock Android

Existe-t-il un moyen meilleur et plus fiable de simuler ces événements tactiles à partir de Java? Merci d'avance!

8
Theo

Comme suggéré, la meilleure façon de simuler des événements tactiles depuis Nougat (API 24) est d'utiliser un service d'accessibilité et la méthode AccessibilityService # dispatchGesture .

Voici comment j'ai fait pour simuler un événement à un seul robinet.

// (x, y) in screen coordinates
private static GestureDescription createClick(float x, float y) {
    // for a single tap a duration of 1 ms is enough
    final int DURATION = 1;

    Path clickPath = new Path();
    clickPath.moveTo(x, y);
    GestureDescription.StrokeDescription clickStroke =
            new GestureDescription.StrokeDescription(clickPath, 0, DURATION);
    GestureDescription.Builder clickBuilder = new GestureDescription.Builder();
    clickBuilder.addStroke(clickStroke);
    return clickBuilder.build();
}

// callback invoked either when the gesture has been completed or cancelled
callback = new AccessibilityService.GestureResultCallback() {
    @Override
    public void onCompleted(GestureDescription gestureDescription) {
        super.onCompleted(gestureDescription);
        Log.d(TAG, "gesture completed");
    }

    @Override
    public void onCancelled(GestureDescription gestureDescription) {
        super.onCancelled(gestureDescription);
        Log.d(TAG, "gesture cancelled");
    }
};

// accessibilityService: contains a reference to an accessibility service
// callback: can be null if you don't care about gesture termination
boolean result = accessibilityService.dispatchGesture(createClick(x, y), callback, null);
Log.d(TAG, "Gesture dispatched? " + result);

Pour effectuer d'autres gestes, vous pourriez trouver utile l'implémentation code utilisé pour les tests l'implémentation AccessibilityService # dispatchGesture.

13
Cesar Mauri