Hamibot 坐标触摸与手势模拟
坐标 vs 控件
上一篇讲的 UiSelector 控件选择器有个前提:目标界面是由标准安卓控件构成的。但有两种情况会失效:
- 游戏画面——游戏引擎绘制的是像素,没有控件树
- 非标准自绘控件——部分 APP 为了性能或外观,自己画了按钮
这时候就要用基于坐标的触摸操作。
获取坐标
在开发者选项里打开「指针位置」或「显示触摸操作」,就能在屏幕上实时看到手指位置的坐标值(x, y)。
分辨率自动适配
直接写坐标的脚本换一台分辨率不同的手机就会点到完全不同的位置。解决方案是 setScreenMetrics()——设定脚本设计时的基准分辨率,实际运行时 Hamibot 会自动放缩坐标。
// 基准分辨率 1080x1920
setScreenMetrics(1080, 1920);
// 下面的所有坐标都会按比例放缩
click(540, 1000); // 在 1080x1920 上点屏幕中央
核心触摸函数
click 点击
click(540, 1000); // 模拟点击坐标,返回是否成功
默认点击过程约 150 毫秒。如果需要更快的连续点击,用 press()。
longClick 长按
longClick(540, 1000); // 长按 600 毫秒
press 按住指定时长
press(540, 1000, 100); // 按住 100 毫秒
// 连点 100 次
for (let i = 0; i < 100; i++) {
press(540, 1000, 1);
}
swipe 滑动
// 从 (540, 1500) 上滑到 (540, 500),用时 300 毫秒
swipe(540, 1500, 540, 500, 300);
gesture 单手势路径
// 模拟一个从 (100, 100) 经过 (500, 500) 到 (900, 900) 的手势,时长 1 秒
gesture(1000, [100, 100], [500, 500], [900, 900]);
gestures 多手势同时
// 模拟双指捏合
gestures(
[0, 500, [800, 300], [500, 1000]], // 手指 A
[0, 500, [300, 1500], [500, 1000]] // 手指 B
);
系统版本要求
以下触摸函数只在 Android 7.0 及以上有效(通过系统 API 注入事件):
click/longClick/pressswipegesture/gestures
Android 7.0 以下需要 root 权限(旧版 Hamibot 有 RootAutomator,现已弃用)。
坐标 + 控件结合
控件不可点击时(clickable 为 false),可以取其中心点坐标用 click() 强行点:
const widget = id("some_control").findOne();
const rect = widget.bounds();
click(rect.centerX(), rect.centerY());
常见坑
不同分辨率适配
写脚本时一定要加 setScreenMetrics(),否则换设备就出问题。
状态栏 / 导航栏偏移
部分 APP 的布局会受到状态栏和导航栏影响,取坐标时要考虑这个偏移。
点击速度过快
系统对手速有检测,短时间内连续点击太多次可能触发限流或被 APP 判定为异常。建议中间加 sleep(50) 等小延时。