触摸操作
本章节介绍了一些使用坐标进行点击、滑动的函数。这些函数有的需要安卓 7.0 以上,有的需要 root 权限。
要获取要点击的位置的坐标,可以在开发者选项中开启"指针位置"。
基于坐标的脚本通常会有分辨率的问题,这时可以通过setScreenMetrics()
函数来进行自动坐标放缩。这个函数会影响本章节的所有点击、长按、滑动等函数。通过设定脚本设计时的分辨率,使得脚本在其他分辨率下自动放缩坐标。
控件和坐标也可以相互结合。一些控件是无法点击的(clickable 为 false), 无法通过.click()
函数来点击,这时如果安卓版本在 7.0 以上或者有 root 权限,就可以通过以下方式来点击:
//获取这个控件
var widget = id('xxx').findOne();
//获取其中心位置并点击
click(widget.bounds().centerX(), widget.bounds().centerY());
//如果用root权限则用Tap
setScreenMetrics(width, height)
- width <Number> 屏幕宽度,单位像素
- height <Number> 屏幕高度,单位像素
设置脚本坐标点击所适合的屏幕宽高。如果脚本运行时,屏幕宽度不一致会自动放缩坐标。
例如在 1920*1080 的设备中,某个操作的代码为
setScreenMetrics(1080, 1920);
click(800, 200);
longClick(300, 500);
那么在其他设备上 Hamibot 会自动放缩坐标以便脚本仍然有效。例如在 540 * 960 的屏幕中click(800, 200)
实际上会点击位置(400, 100)。
安卓 7.0 以上的触摸和手势模拟
注意以下命令只有 Android 7.0 及以上才有效
click(x, y)
x
<Number> 要点击的坐标的 x 值y
<Number> 要点击的坐标的 y 值
模拟点击坐标(x, y),并返回是否点击成功。只有在点击执行完成后脚本才继续执行。
一般而言,只有点击过程(大约 150 毫秒)中被其他事件中断(例如用户自行点击)才会点击失败。
使用该函数模拟连续点击时可能有点击速度过慢的问题,这时可以用press()
函数代替。
longClick(x, y)
x
<Number> 要长按的坐标的 x 值y
<Number> 要长按的坐标的 y 值
模拟长按坐标(x, y), 并返回是否成功。只有在长按执行完成(大约 600 毫秒)时脚本才会继续执行。
一般而言,只有长按过程中被其他事件中断(例如用户自行点击)才会长按失败。
press(x, y, duration)
x
<Number> 要按住的坐标的 x 值y
<Number> 要按住的坐标的 y 值duration
<Number> 按住时长,单位毫秒
模拟按住坐标(x, y), 并返回是否成功。只有按住操作执行完成时脚本才会继续执行。
如果按住时间过短,那么会被系统认为是点击;如果时长超过 500 毫秒,则认为是长按。
一般而言,只有按住过程中被其他事件中断才会操作失败。
一个连点器的例子如下:
//循环100次
for (var i = 0; i < 100; i++) {
//点击位置(500, 1000), 每次用时1毫秒
press(500, 1000, 1);
}
swipe(x1, y1, x2, y2, duration)
x1
<Number> 滑动的起始坐标的 x 值y1
<Number> 滑动的起始坐标的 y 值x2
<Number> 滑动的结束坐标的 x 值y2
<Number> 滑动的结束坐标的 y 值duration
<Number> 滑动时长,单位毫秒
模拟从坐标(x1, y1)滑动到坐标(x2, y2),并返回是否成功。只有滑动操作执行完成时脚本才会继续执行。
一般而言,只有滑动过程中被其他事件中断才会滑动失败。
gesture(duration, [x1, y1], [x2, y2], ...)
duration
<Number> 手势的时长- [x, y] ... 手势滑动路径的一系列坐标
模拟手势操作。例如gesture(1000, [0, 0], [500, 500], [500, 1000])
为模拟一个从(0, 0)到(500, 500)到(500, 100)的手势操作,时长为 2 秒。
gestures([delay1, duration1, [x1, y1], [x2, y2], ...], [delay2, duration2, [x3, y3], [x4, y4], ...], ...)
同时模拟多个手势。每个手势的参数为[delay, duration, 坐标], delay 为延迟多久(毫秒)才执行该手势;duration 为手势执行时长;坐标为手势经过的点的坐标。其中 delay 参数可以省略,默认为 0。
例如手指捏合:
gestures([0, 500, [800, 300], [500, 1000]], [0, 500, [300, 1500], [500, 1000]]);
RootAutomator
RootAutomator 是一个使用 root 权限来模拟触摸的对象,用它可以完成触摸与多点触摸,并且这些动作的执行没有延迟。
一个脚本中最好只存在一个 RootAutomator,并且保证脚本结束退出他。可以在 exit 事件中退出 RootAutomator,例如:
var ra = new RootAutomator();
events.on('exit', function() {
ra.exit();
});
//执行一些点击操作
...
注意以下命令需要 root 权限
RootAutomator.tap(x, y[, id])
x
<Number> 横坐标y
<Number> 纵坐标id
<Number> 多点触摸 id,可选,默认为 1,可以通过 setDefaultId 指定。
点击位置(x, y)。其中 id 是一个整数值,用于区分多点触摸,不同的 id 表示不同的"手指",例如:
var ra = new RootAutomator();
//让"手指1"点击位置(100, 100)
ra.tap(100, 100, 1);
//让"手指2"点击位置(200, 200);
ra.tap(200, 200, 2);
ra.exit();
如果不需要多点触摸,则不需要 id 这个参数。 多点触摸通常用于手势或游戏操作,例如模拟双指捏合、双指上滑等。
某些情况下可能存在 tap 点击无反应的情况,这时可以用RootAutomator.press()
函数代替。
RootAutomator.swipe(x1, y1, x2, y2[, duration, id])
x1
<Number> 滑动起点横坐标y1
<Number> 滑动起点纵坐标x2
<Number> 滑动终点横坐标y2
<Number> 滑动终点纵坐标duration
<Number> 滑动时长,单位毫秒,默认值为 300id
<Number> 多点触摸 id,可选,默认为 1
模拟一次从(x1, y1)到(x2, y2)的时间为 duration 毫秒的滑动。
RootAutomator.press(x, y, duration[, id])
x
<Number> 横坐标y
<Number> 纵坐标duration
<Number> 按下时长id
<Number> 多点触摸 id,可选,默认为 1
模拟按下位置(x, y),时长为 duration 毫秒。
RootAutomator.longPress(x, y, duration[, id])
x
<Number> 横坐标y
<Number> 纵坐标duration
<Number> 按下时长id
<Number> 多点触摸 id,可选,默认为 1
模拟长按位置(x, y)。
以上为简单模拟触摸操作的函数。如果要模拟一些复杂的手势,需要更底层的函数。
RootAutomator.touchDown(x, y[, id])
x
<Number> 横坐标y
<Number> 纵坐标id
<Number> 多点触摸 id,可选,默认为 1
模拟手指按下位置(x, y)。
RootAutomator.touchMove(x, y[, id])
x
<Number> 横坐标y
<Number> 纵坐标id
<Number> 多点触摸 id,可选,默认为 1
模拟移动手指到位置(x, y)。
RootAutomator.touchUp([id])
id
<Number> 多点触摸 id,可选,默认为 1
模拟手指弹起。
使用 root 权限点击和滑动的简单命令
注意:本章节的函数在后续版本很可能有改动!请勿过分依赖本章节函数的副作用。推荐使用RootAutomator
代替本章节的触摸函数。
以下函数均需要 root 权限,可以实现任意位置的点击、滑动等。
- 这些函数通常首字母大写以表示其特殊的权限。
- 这些函数均不返回任何值。
- 并且,这些函数的执行是异步的、非阻塞的,在不同机型上所用的时间不同。脚本不会等待动作执行完成才继续执行。因此最好在每个函数之后加上适当的 sleep 来达到期望的效果。
例如:
Tap(100, 100);
sleep(500);
注意,动作的执行可能无法被停止,例如:
for (var i = 0; i < 100; i++) {
Tap(100, 100);
}
这段代码执行后可能会出现在任务管理中停止脚本后点击仍然继续的情况。 因此,强烈建议在每个动作后加上延时:
for (var i = 0; i < 100; i++) {
Tap(100, 100);
sleep(500);
}
Tap(x, y)
- x, y <Number> 要点击的坐标。
点击位置(x, y), 您可以通过"开发者选项"开启指针位置来确定点击坐标。
Swipe(x1, y1, x2, y2, [duration])
- x1, y1 <Number> 滑动起点的坐标
- x2, y2 <Number> 滑动终点的坐标
- duration <Number> 滑动动作所用的时间
滑动。从(x1, y1)位置滑动到(x2, y2)位置。