Java 我如何在没有root的情况下可靠地模拟Android上的触摸事件(如Automatic和Tasker)?

Java 我如何在没有root的情况下可靠地模拟Android上的触摸事件(如Automatic和Tasker)?,java,android,android-8.0-oreo,accessibilityservice,Java,Android,Android 8.0 Oreo,Accessibilityservice,如何在Android上可靠地模拟作为后台服务运行的应用程序之外的Java上的触摸事件(无需根) 虽然以前有人问过这个问题,大多数答案都使用ADB。 (例如) 使用可访问性提供了一个很好的解决方案,但不是很可靠,因为不是所有视图都响应它,而且大多数时候游戏都不会响应 private void click() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo == null) return;

如何在Android上可靠地模拟作为后台服务运行的应用程序之外的Java上的触摸事件(无需根)

虽然以前有人问过这个问题,大多数答案都使用ADB。 (例如)

使用可访问性提供了一个很好的解决方案,但不是很可靠,因为不是所有视图都响应它,而且大多数时候游戏都不会响应

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();
}
这是所使用的当前代码

安卓版本是8.0,股票安卓


有没有更好、更可靠的方法从Java模拟这些触摸事件?提前谢谢

正如所建议的,自Nougat(API 24)以来模拟触摸事件的最佳方法是使用可访问性服务和方法

下面是我如何模拟单个点击事件的

// (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);
要执行其他手势,您可能会发现AccessibilityService#Dispatch手势实现非常有用


编辑:我在我的博客中链接了一篇文章。

可能对基于可访问性的方法进行了改进,因为我不熟悉该代码的细节。但是,一般来说,可访问性和根目录是您唯一的选择。嘿@Theo您是如何解决这个问题的?我建议您签出和相应的文档。他们实际上应该执行原始手势,而不依赖于开发人员正确实现onClick。@Commonware,例如Team View QuickSupport today权限,这意味着任何请求此权限的应用程序都能够在非根设备中模拟触摸事件?我在AOSP中没有看到被称为“特殊访问”的权限。我猜这是TeamViewer与设备制造商达成的特定协议。是否有办法在低于24的api级别上实现触摸。我注意到你的应用程序“eva_facial_mouse”在api级别低于24的android手机上执行点击。@AkashKarnatak,在某种程度上,这是可能的。EVA使用AccessibilityNodeInfo#性能方法执行taps。这意味着您首先需要找到要点击的正确节点。这通常涉及从根开始搜索可访问性节点树。然而,根据我的经验,并不是所有的应用程序都能提供这样一棵树,因为游戏是主要的违规者。下面是我在EVA中实际实现的方式:您能再提供一些关于这个API的信息吗?它是否是一个开放供任何应用程序使用的API,可以通过自由指定几何和时间(路径中每个点的触摸路径和速度)来模拟任何形式的触摸笔划或轻触触摸路径允许应用程序开发人员实际开发可访问性解决方案,以取代触摸手机显示区域的需要。非常好的文章,谢谢:)这对我有用谢谢!需要注意的是,可访问性服务xml需要有“android:canPerformGestures=true”才能工作。