跳至主要內容

automator与其他函数

约 2924 字大约 10 分钟老猫

auto([mode])

  • mode {string} 模式

检查无障碍服务是否已经启用,如果没有启用则抛出异常并跳转到无障碍服务启用界面;同时设置无障碍模式为mode。mode的可选值为:

  • fast 快速模式。该模式下会启用控件缓存,从而选择器获取屏幕控件更快。对于需要快速的控件操作的脚本可以使用该模式,一般脚本则没有必要使用该函数。
  • normal 正常模式,默认。

如果不加mode参数,则为正常模式。

建议使用auto.waitFor()auto.setMode()代替该函数,因为auto()函数如果无障碍服务未启动会停止脚本;而auto.waitFor()则会在在无障碍服务启动后继续运行。

示例:

auto("fast");

示例2:

auto();

auto.waitFor()

检查无障碍服务是否已经启用,如果没有启用则跳转到无障碍服务启用界面,并等待无障碍服务启动;当无障碍服务启动后脚本会继续运行。

因为该函数是阻塞的,因此除非是有协程特性,否则不能在ui模式下运行该函数,建议在ui模式下使用auto()函数。

auto.setMode(mode)

  • mode {string} 模式

设置无障碍模式为mode。mode的可选值为:

  • fast 快速模式。该模式下会启用控件缓存,从而选择器获取屏幕控件更快。对于需要快速的控件查看和操作的脚本可以使用该模式,一般脚本则没有必要使用该函数。
  • normal 正常模式,默认。

auto.setFlags(flags)

[v4.1.0新增]

  • flags {string} | {Array} 一些标志,来启用和禁用某些特性,包括:

    • findOnUiThread 使用该特性后,选择器搜索时会在主进程进行。该特性用于解决线程安全问题导致的次生问题,不过目前貌似已知问题并不是线程安全问题。
    • useUsageStats 使用该特性后,将会以"使用情况统计"服务的结果来检测当前正在运行的应用包名(需要授予"查看使用情况统计"权限)。如果觉得currentPackage()返回的结果不太准确,可以尝试该特性。
    • useShell 使用该特性后,将使用shell命令获取当前正在运行的应用的包名、活动名称,但是需要root权限。

启用有关automator的一些特性。例如:

auto.setFlags(["findOnUiThread", "useShell"]);

auto.service

[v4.1.0新增]

获取无障碍服务。如果无障碍服务没有启动,则返回null

参见AccessibilityServiceopen in new window

auto.windows

[v4.1.0新增]

  • {Array}

当前所有窗口(AccessibilityWindowInfoopen in new window)的数组,可能包括状态栏、输入法、当前应用窗口,弹出窗口、悬浮窗、分屏应用窗口等。可以分别获取每个窗口的布局信息。

该函数需要Android 5.0以上才能运行。

auto.root

[v4.1.0新增]

  • {UiObject}

当前窗口的布局根元素。如果无障碍服务未启动或者WindowFilter均返回false,则会返回null

如果不设置windowFilter,则当前窗口即为活跃的窗口(获取到焦点、正在触摸的窗口);如果设置了windowFilter,则获取的是过滤的窗口中的第一个窗口。

如果系统是Android5.0以下,则始终返回当前活跃的窗口的布局根元素。

auto.rootInActiveWindow

[v4.1.0新增]

  • {UiObject}

当前活跃的窗口(获取到焦点、正在触摸的窗口)的布局根元素。如果无障碍服务未启动则为null

auto.setWindowFilter(filter)

[v4.1.0新增]

设置窗口过滤器。这个过滤器可以决定哪些窗口是目标窗口,并影响选择器的搜索。例如,如果想要选择器在所有窗口(包括状态栏、输入法等)中搜索,只需要使用以下代码:

auto.setWindowFilter(function(window){
    //不管是如何窗口,都返回true,表示在该窗口中搜索
    return true;
});

又例如,当前使用了分屏功能,屏幕上有Auto.js和QQ两个应用,但我们只想选择器对QQ界面进行搜索,则:

auto.setWindowFilter(function(window){
    // 对于应用窗口,他的title属性就是应用的名称,因此可以通过title属性来判断一个应用
    return window.title == "QQ";
});

选择器默认是在当前活跃的窗口中搜索,不会搜索诸如悬浮窗、状态栏之类的,使用WindowFilter则可以控制搜索的窗口。

需要注意的是, 如果WindowFilter返回的结果均为false,则选择器的搜索结果将为空。

另外setWindowFilter函数也会影响auto.windowRoots的结果。

该函数需要Android 5.0以上才有效。

auto.windowRoots

[v4.1.0新增]

  • {Array}

返回当前被WindowFilter过滤的窗口的布局根元素组成的数组。

如果系统是Android5.0以下,则始终返回当前活跃的窗口的布局根元素的数组。

automator

automator提供了一些模拟简单操作的函数,例如点击文字、模拟按键等。部分函数可以直接作为全局函数使用。

click(text[, i])

  • text {string} 要点击的文本
  • i {number} 如果相同的文本在屏幕中出现多次,则i表示要点击第几个文本, i从0开始计算

返回是否点击成功。当屏幕中并未包含该文本,或者该文本所在区域不能点击时返回false,否则返回true。

该函数可以点击大部分包含文字的按钮。例如微信主界面下方的"微信", "联系人", "发现", "我"的按钮。
通常与while同时使用以便点击按钮直至成功。例如:

while(!click("扫一扫"));

当不指定参数i时则会尝试点击屏幕上出现的所有文字text并返回是否全部点击成功。

i是从0开始计算的, 也就是, click("啦啦啦", 0)表示点击屏幕上第一个"啦啦啦", click("啦啦啦", 1)表示点击屏幕上第二个"啦啦啦"。

文本所在区域指的是,从文本处向其父视图寻找,直至发现一个可点击的部件为止。

click(left, top, bottom, right)

  • left {number} 要点击的长方形区域左边与屏幕左边的像素距离
  • top {number} 要点击的长方形区域上边与屏幕上边的像素距离
  • bottom {number} 要点击的长方形区域下边与屏幕下边的像素距离
  • right {number} 要点击的长方形区域右边与屏幕右边的像素距离

注意,该函数一般只用于录制的脚本中使用,在自己写的代码中使用该函数一般不要使用该函数。

点击在指定区域的控件。当屏幕中并未包含与该区域严格匹配的区域,或者该区域不能点击时返回false,否则返回true。

有些按钮或者部件是图标而不是文字(例如发送朋友圈的照相机图标以及QQ下方的消息、联系人、动态图标),这时不能通过click(text, i)来点击,可以通过描述图标所在的区域来点击。left, bottom, top, right描述的就是点击的区域。

至于要定位点击的区域,可以在悬浮窗使用布局分析工具查看控件的bounds属性。

通过无障碍服务录制脚本会生成该语句。

longClick(text[, i])

  • text {string} 要长按的文本
  • i {number} 如果相同的文本在屏幕中出现多次,则i表示要长按第几个文本, i从0开始计算

返回是否点击成功。当屏幕中并未包含该文本,或者该文本所在区域不能点击时返回false,否则返回true。

当不指定参数i时则会尝试点击屏幕上出现的所有文字text并返回是否全部长按成功。

scrollUp([i])

  • i {number} 要滑动的控件序号

找到第i+1个可滑动控件上滑或左滑。返回是否操作成功。屏幕上没有可滑动的控件时返回false。

另外不加参数时scrollUp()会寻找面积最大的可滑动的控件上滑或左滑,例如微信消息列表等。

参数为一个整数i时会找到第i + 1个可滑动控件滑动。例如scrollUp(0)为滑动第一个可滑动控件。

scrollDown([i])

  • i {number} 要滑动的控件序号

找到第i+1个可滑动控件下滑或右滑。返回是否操作成功。屏幕上没有可滑动的控件时返回false。

另外不加参数时scrollUp()会寻找面积最大的可滑动的控件下滑或右滑。

参数为一个整数i时会找到第i + 1个可滑动控件滑动。例如scrollUp(0)为滑动第一个可滑动控件。

setText([i, ]text)

  • i {number} 表示要输入的为第i + 1个输入框
  • text {string} 要输入的文本

返回是否输入成功。当找不到对应的文本框时返回false。

不加参数i则会把所有输入框的文本都置为text。例如setText("测试")

这里的输入文本的意思是,把输入框的文本置为text,而不是在原来的文本上追加。

input([i, ]text)

  • i {number} 表示要输入的为第i + 1个输入框
  • text {string} 要输入的文本

返回是否输入成功。当找不到对应的文本框时返回false。

不加参数i则会把所有输入框的文本追加内容text。例如input("测试")

automator.takeScreenshot()

[Pro 8.8.0新增open in new window]

  • 返回 {Image}

使用无障碍权限截图,返回一个Image对象。

相比起images模块申请截图权限截图,该函数不需要额外权限,但是有以下限制:

  • 截图频率限制。系统限制截图最多一秒一次,否则抛出异常
  • 需要Android 11及以上版本
$auto.waitFor();
let capture = $automator.takeScreenshot();
$images.save(capture, "../capture.png");

automator.switchToInputMethod(packageName)

[Pro 8.8.0新增]

  • packageName {string} 输入法包名
  • 返回 {boolean}

切换到指定输入法,返回是否成功。失败的情况有以下可能:

  • 指定包名的输入法不存在或未启用
  • 系统返回切换输入法失败

此函数需要Android 11及以上。

// 切换到搜狗输入法
$automator.switchToInputMethod('com.sohu.inputmethod.sogou')

automator.headsetHook()

[Pro 8.8.0新增]

  • 返回 {boolean}

模拟耳机键,返回是否执行成功。用于挂断、接听电话,播放、暂停音乐。

auto.clearCache()

[v9.0.14新增]

清空无障碍缓存。当屏幕上的控件已经出现但是选择器始终无法找到该控件,可能是缓存没有刷新,此时可调用auto.clearCache()来清空控件缓存。另外,从9.0版本开始,findOne()等函数在长时间找不到时也会自动清空缓存。

Rect

UiObject.bounds(), UiObject.boundsInParent()返回的对象。表示一个长方形(范围)。

Rect.left

  • {number}

长方形左边界的x坐标、

Rect.right

  • {number}

长方形右边界的x坐标、

Rect.top

  • {number}

长方形上边界的y坐标、

Rect.bottom

  • {number}

长方形下边界的y坐标、

Rect.centerX()

  • 返回 {number}

长方形中点x坐标。

Rect.centerY()

  • 返回 {number}

长方形中点y坐标。

Rect.width()

  • 返回 {number}

长方形宽度。通常可以作为控件宽度。

Rect.height()

  • 返回 {number}

长方形高度。通常可以作为控件高度。

Rect.contains(r)

返回是否包含另一个长方形r。包含指的是,长方形r在该长方形的里面(包含边界重叠的情况)。

Rect.intersect(r)

返回是否和另一个长方形相交。