How can I reliably simulate touch events on Android without root (like Automate and Tasker)?

混江龙づ霸主 提交于 2019-11-27 03:34:28

问题


How can I reliably simulate touch events on Android (without rooting) from Java outside my app which runs as a background service?

While this question has been asked before, most answers utilise ADB. (such as How to simulate touch events on Android device?)

https://github.com/chetbox/android-mouse-cursor offers a good solution using Accessibility, but is not very reliable as not all views respond to it, and games do not respond at all most of the time.

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

This is the current code used by https://github.com/chetbox/android-mouse-cursor.

Android Version is 8.0, stock Android

Is there a better, more reliable way to simulate these touch events from Java? Thanks in advance!


回答1:


As suggested, the best way to simulate touch events since Nougat (API 24) is by using an accessibility service and the AccessibilityService#dispatchGesture method.

Here is how I did to simulate a single tap event.

// (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);

To perform other gestures, you might find useful the code used for testing the AccessibilityService#dispatchGesture implementation.



来源:https://stackoverflow.com/questions/50775698/how-can-i-reliably-simulate-touch-events-on-android-without-root-like-automate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!