组件
Total Control 是一个由许多组件/模块和功能组成的大型系统:
TCW 中有许多应用程序:
连接
安装 Total Control 后,对于每个 Android 设备,首要任务是建立 USB 连接,这个过程虽然繁琐,但在两个方面非常重要:
为了获得 adb/shell 权限,需要在“开发者选项”中启用“USB 调试”,一旦正确安装了 adb 设备驱动程序并启用了调试选项,Total Control 将能够访问设备并使用 adb 将“Total Control”应用程序和 NDK 软件安装到设备中。Windows 10 可以识别大多数 Android 设备,而 Windows 7 和 XP 则需要 adb 设备驱动程序。我们提供了一款通用的 adb 设备驱动程序,适用于大多数设备,如果不起作用,可能需要访问设备制造商的网站下载 adb 设备驱动程序。
Total Control 自动检测 USB 设备的存在并要求确认连接,它提供了如何打开各种设备型号的“开发者选项”和启用“USB 调试”的说明,在设置过程中,设备(而不是电脑)可能会弹出一个消息来确认连接。通过 USB 建立连接是最困难的部分,这是一次性的设置,一旦“连接”按钮出现,表示您已经正确安装了所有内容。点击“连接”按钮,您可能会看到一个设备窗口,请按照屏幕上的指示进行测试。
USB 连接建立后,软件已被授予权限,您现在可以继续使用它,或者拔掉 USB 并通过 WiFi 或以太网建立连接。
TCP 连接
一旦您通过 USB 连接打开设备窗口,设备已获得 adb 权限,现在您可以拔掉 USB,并选择使用 WiFi 或以太网(或其他具有 IP 地址的网络方法)来添加设备。要通过 TCP 添加设备,可以在主窗口中使用“+ 连接新设备”或“未找到设备,点击此处开始”,这将打开一个连接窗口。有两种通过 TCP 连接的方法:
设备设置还支持 USB 和 TCP 的“自动连接”,它将自动连接并打开设备窗口。它不提供以太网自动连接,而 WiFi 自动连接允许设备检测访问点的存在,自动发现并连接到 TC。
只要设备被授予 adb 权限,TCP 连接就可以非常强大,它允许 TC 在任何可达网络中连接/控制设备,在使用 VPN 时,可以连接多个远程位置的设备。Total Control 8 还添加了 TCP 分组功能,方便通过 TCP 连接多个设备。
屏幕镜像
如果您只想进行屏幕镜像而不需要控制设备,请在连接窗口中选择“镜像”,它将显示一个 QR 码,与 TCP 连接相同,使用您的设备中的“Total Control”应用程序扫描该码,如果可达,将显示“连接”按钮,点击即可显示屏幕。该模式不允许用户控制设备。
窗口
Total Control 有两种模式:Windows 桌面模式(Windows Desktop Mode,简称 WDM)和多设备控制中心(Multi-Device Control Center,简称 MDCC),MDCC 是完全不同的模式,我们将在后面的章节中专门介绍它。为简单起见,我们将在大部分章节中描述 WDM。
不同类型的窗口有几种类型和功能:
设备窗口
设备窗口将在以下情况下自动打开(自动连接)或在连接窗口中点击“连接”按钮时打开。设备窗口由以下几个组件组成:
设备菜单
在设备窗口中点击三个水平线将弹出一个功能菜单:
设备设置
设备设置用于微调设备的行为,它具有许多选项,其中大多数选项使用默认值即可良好运行:
屏幕设备设置
我们付出了大量努力来确保屏幕传输的高效性,如何在不牺牲高性能 PC(<10% 的 CPU 使用率)的情况下实现每秒 40-60 帧的传输。设备和 PC 上 GPU 的高效利用至关重要,任一方的 GPU 缺失都会显著降低镜像的速度。我们还拥有自主研发的压缩技术(SFC)来处理没有 GPU 的设备。我们将执行图像压缩(H.264 或自主开发的压缩算法),进行传输、解压缩和在 PC 上呈现。PC 必须处理多个设备。图像质量(质量 + 延迟)受许多因素的影响:每秒帧数、每帧的数据大小(分辨率、质量)、USB 传输速率、adb 传输速率、设备和 PC 的 CPU/GPU。我们提供许多参数进行调整。
分辨率
Lite 版本提供 640p 分辨率,Pro 版本提供 4 种分辨率,我们会保持宽高比,调整操作在设备上进行。例如,具有 4K 分辨率的设备对 PC 上的屏幕质量几乎没有影响,但 1080p 分辨率则有影响。1080p 将给设备和 PC 带来较大负担(生成和传输更多数据)。
设备加速
有 3 种加速方法:
图像质量
我们提供 3 种图像质量:低、中、高,通过调整 H.264 的比特率来实现,图像质量对静态图像没有影响(如果图像没有更新,设备将传输高质量的静态图像),但在动态图像中更为明显。
[高级] 设备编码设置
调整 H.264 编码配置文件以获得更高的图像质量,Android 要求基本配置文件,不是所有设备都支持其他配置文件。
[高级] 电脑加速
TC 被优化以利用 Intel i 系列 CPU/GPU,如果您有外部显卡,可以调整 DirectX 或 OpenGL 来获得更好的性能。通常,DirectX 已经足够好。
[高级] 硬件加速
对于 HA1 和 HA2,它将让 GPU 在一步中进行解压缩和呈现。如果未选中此模式,将会将解压缩(GPU)和呈现作为两个独立步骤进行(移动大量数据)。
[高级] Native 与 Projection
在 Android 12 之前,我们可以使用自己的代码进行 H.264 或 SFC 压缩,我们称之为 "Native" 模式,随着 Android 引入 "屏幕投影" 功能,我们已将 "Projection" 添加到 Total Control 中。Android 投影的速度与(如果不是更快的话)我们的 "Native" 模式相似,对于我们来说,维护每个新 Android 发布的两种模式是困难的。从 Android 12 开始,我们将不再提供 "Native" 模式或 SFC。
系统设置
系统设置是适用于所有设备的设置。可以通过主窗口设置或设备设置 ⇒ 系统设置访问。它由左侧的主题和右侧的详细设置组成,您可以在右侧滚动并单击左侧的标题。其中包含以下设置:
Sigma 键盘
其他选项
截屏、视频录制 – 详见 截屏和视频录制。
捕捉屏幕– 详见 复制粘贴和文件传输。
复制 – 详见 复制粘贴和文件传输。
分享图像时保存/剪贴板。详见 复制粘贴和文件传输。
老板键 – 可以定义一个功能键,用于关闭 Windows 系统托盘中的所有设备窗口。
屏幕控制模式 – 详见 移动、点击和滑动。
adb/adb2 – adb2 是比 adb 更新且速度更快的版本,如果在 adb2 上遇到问题,可以切换到 adb。
设备自动休眠 – 默认情况下,TC 会保持设备屏幕始终亮着,选中此选项可使用设备的显示超时设置。
备份 – 备份和还原联系人、短信和通话记录的路径。
每秒帧数 – 显示每秒帧数。
显示坐标 – 显示鼠标指针相对于设备屏幕的绝对和相对坐标,对于需要 x 和 y 坐标的 API 非常有用。
设备显示模式 – MDCC 或 WDM。MDCC 将在不同的部分中。
快捷方式 – 这允许用户定义最多 4 个快捷方式,以便在设备窗口的顶部快速访问。其中大多数都是不言自明的,"Sigma 输入" 将允许用户选择输入方法。
通知管理 – 可以定义存储的通知数量以及接收通知时的操作。
自动启动 – 这是一个小型 PC 软件,允许用户启动/退出/重新启动 Total Control,或者如果带有自动连接功能的设备插入 USB 端口,则会自动启动。
REST API – 定义 REST API 的用户名和密码,默认情况下,出于安全原因,密码是 TC ID 的最后 8 个字符。"持续时间设置" 是发送另一个 "身份验证" 所需的时间。如果您的 PC 上存在端口号冲突,可以更改端口号。其余是计费信息和连接列表。
语音 – 详见 语音控制 获取更多信息。
移动、点击和滑动
移动操作可能是您首先要测试的内容,我们通过滑动或滚动、键盘的四个方向键、PgUp、PgDn、Home、End(菜单)来模拟移动屏幕。使用 Shift 键加上四个方向键可以在屏幕中间进行长滑动,对于浏览图片或应用程序界面上的下一页非常有用。Shift-PgUp 和 Shift-PgDn 可以快速滑动到文档的最前面和最底部(尽可能快地滑动)。
有三个关键键很重要:"Esc"、"Tab" 和 "Enter"。"Esc" 键相当于 Android 的返回键 "<"。某些应用程序提供 Enter 键作为发送键,使用 Enter 键可以方便地发送内容,而不需要点击发送按钮。由于没有光标,可以使用 "Tab" 和 "Enter" 浏览一些选项。按 Enter 键可以进行搜索,按额外的 Enter 键。
另外,鼠标也可以用于控制操作,鼠标滚轮可以代替 "上" 和 "下" 键,左键用于点击或滑动。右键有两个功能:
在系统选项的 "屏幕控制模式" 中,您可以选择 "滚动(scroll)",在可能的情况下使用 Android 的滚动功能(除 Shift-Up/Down/Left/Right 以外的所有移动键)。
文本输入
Total Control 处理输入的方式是在设备上安装一个名为 "Sigma Keyboard" 的键盘,"Sigma Keyboard" 是一个不可见的键盘,在后台与 PC 上的 Total Control 进行通信。建议始终使用 Sigma Keyboard,因为它允许用户使用 PC 上的键盘输入文本。系统设置中有一个选项始终使用 Sigma Keyboard。当需要文本输入时,将在设备窗口的顶部出现一个文本框,用户可以通过 Windows 提供的首选语言和输入系统在文本框中输入文本。用户有三个输入选项可供选择:
还有另一个选项 "a",很少使用,因为它是逐个字母输入,通常在终端软件中有用。文本框提供了许多功能:
当文本框出现时,导航键(如上/下/左/右或 PgUp/PgDn)适用于文本框,您需要使用 Escape 键关闭文本框。
当 USB 断开连接时,设备的 Total Control 将恢复其键盘到先前的设置。
如果您想使用特定的键盘,请在设备窗口中选择菜单 "Change Keyboard" 选项来更改键盘。
复制粘贴和文件传输
借助 Sigma Keyboard 的支持,您可以在 PC 和设备之间进行剪切粘贴,Total Control 还支持文件传输:
截屏和视频录制
有关更多选项,请查看系统设置中的截屏和视频录制。
有几种方法可以进行截屏:
可用的三种格式为 BMP、PNG 和 JPG。截屏是在设备上执行的(而不是现有设备屏幕),它将按原生分辨率进行,如果您的设备屏幕具有高分辨率(例如 4K),请不要使用 BMP,将需要很长时间将大型 BMP 数据传输到 PC(或者存储时间很长)。使用无损的 PNG 或 JPG(通过滑块设置质量)以节省空间。
截图可以存储为文件或剪贴板,文件存储在文件路径中,对于剪贴板,您可以在诸如 "画图" 的图形程序中粘贴。
对于具有高分辨率屏幕(2K 或以上)的 PC,以原生分辨率进行捕捉将导致要传输到设备的大型文件。 "调整为 1080p" 是默认选项,它将屏幕视为 1080p 并进行相应调整。
对于视频录制,当打开视频录制时,会出现一个计时器,点击红色矩形停止录制。以下是一些注意事项:
TC 利用 Windows 7 和 10 的语音功能,允许用户使用语音打开应用程序或运行功能(参见 Userlib.js)。默认情况下,设备中的所有应用程序都将被注册,因此您可以使用 "打开<应用程序名称>" 来打开一个应用程序,例如 "打开日历" 来打开日历应用。如果应用程序不是英文单词或发音困难(尤其是游戏名称),您可以将短语与应用关联起来。
您还可以将短语与 Userlib.js 中的函数名称关联起来。当听到一个词时,它将执行一个以设备 ID 作为唯一参数的函数。例如,将 "现在离开" 配置给函数 leaveNow。您可以在 Userlib.js 中创建一个函数:function leaveNow(device) {…}
触发短语是 "OK TC",一个弹出窗口将打开并准备接收命令。如果第一个词是 "multiple",用户可以提供一系列命令,直到听到 "stop" 或 60 秒内没有可用的命令。动作将在主设备上执行。
出于安全原因,语音控制功能需要 "打开" 来侦听触发短语,打开一个设备将为所有设备打开。如果在系统设置中,您可以选择 "始终启用" 以自动打开。
功能 | 语音 |
---|---|
唤醒词 | 小控小控 |
切换到多指令模式 | 多 |
退出多指令模式 | 停止 |
应用程序 | 打开 "应用程序名称" |
打开 <短语>; 短语 = "应用程序名称" | |
Function | 运行 <短语>; 短语 = "Function名称" |
功能 | 键盘 | 语音 | 键盘 | 语音 |
---|---|---|---|---|
移动 | 向上箭头 | 上 | Page Up | 上页 |
向下箭头 | 下 | Page Down | 下页 | |
向左箭头 | 左 | Shift + Page Up | 回顶部 | |
向右箭头 | 右 | Shift + Page Down | 底部 | |
滑动 | Shift + 向左箭头 | 左滑 | Shift + 向上箭头 | 上滑 |
Shift + 向右箭头 | 右滑 | Shift + 向下箭头 | 下滑 | |
特殊功能 | Home | 主页 | Escape | 返回 |
End | 菜单 |
付费功能
Total Control 提供精简版,可免费用于非商业用途。所有 Total Control 付费功能都是基于 PC 的年度订阅计划。要购买,点击购物车图标,选择您要购买的功能,选择结帐,支付方式,支付完成后,在PC上重启Total Control,授权将升级为新购买的功能。
Total Control 提供 2 种付款方式:
MDC-x
由于专业版包含其他付费功能的基本功能,因此用户必须在购买其他功能之前购买专业版。如果您计划在以后购买额外的付费功能,则专业版 1 年订阅到期日期很重要。例如,您在 6 个月前购买了专业版并决定购买 MDC-20,您只需支付 MDC-20 价格的一半,MDC-20 的到期日期与专业版相同。此外,如果您计划在 3 个月后(专业版 9 个月后)购买 MDC-30,您只需支付差价(TC 扣除未使用时间):
(价格(新)- 价格(旧))/365 * 距离专业版到期的剩余天数
在这种情况下:
(价格(MDC-30) – 价格(MDC-20))/365 * 90 天 (3 个月)
所有 MDC-x 都可以通过支付方式升级到更多数量的设备。
Device Control
Device Control 是一个独立的安卓应用程序(称为TC Viewer),允许多控中心用户选择一个设备来控制主设备,一些应用程序更容易通过设备导航而不是使用鼠标和键盘来控制它们。查看器应用程序可以是连接到 多控中心 的设备之一,也可以在运行 TC 的 PC 可访问的任何设备上运行(甚至在数千英里外的 VPN 上)。如果您正在运行 多控中心,如果您在 多控中心,您可以选择任何设备单击 DC 图标,如果您使用 TCP 连接到 多控中心,请在此处下载应用程序。
购买完成后会发送订阅确认邮件并附上“激活码”,如果您打算将Total Control 移至新 PC 或需要重新安装操作系统,请先在新 PC 中安装精简版 PC/OS,使用激活码激活付费功能,输入有效激活码后会生成新的激活码,请妥善保管。您每年只能进行 10 次迁移。
我们提供 2 种付款方式:
项目代码 | 描述 | # 设备 |
---|---|---|
TC 精简版 | 免费版,提供许多基本功能 | 2 |
TC 专业版 | 专业,提供许多附加功能 | 4 |
多设备控制 (10) | Total Control 支持 10 台设备 | 10 |
多设备控制 (20) | Total Control 支持 20 台设备 | 20 |
多设备控制 (30) | Total Control 支持 30 台设备 | 30 |
多设备控制 (50) | Total Control 支持 50 台设备 | 50 |
Device Control | 设备控制 PC-TC 控制其他设备 | 不适用 |
快捷方式
Total Control 实现了几种快捷方式来改善用户体验,有两种类型的快捷方式,一种适用于设备(在设备设置中),另一种适用于整个系统(在系统设置中):
脚本编写
Total Control 最大的优势之一就是其脚本编写功能。Total Control 提供了丰富的 API,可以控制一个或多个 Android 设备。它提供了两套 API:JavaScript 和 REST API。JavaScript 可以在本地运行脚本,REST API 则提供了语言和主机的灵活性。您还可以使用 REST API 来控制运行 "Total Control" 应用程序的多台计算机。
JavaScript API
语言
Total Control 提供以下 JavaScript 框架(ECMAScript 5,包括一些 ES6 特性):
Rhino 的优势在于可以直接调用 Java API(Total Control 8 使用的是 OpenJDK 15),如果 Rhino + RingoJS 提供的功能不足以满足需求。
Total Control 提供了许多类,以下是一些示例:
Device 和 DeviceArray 类
当设备连接时(自动连接或按下“连接”按钮),将创建一个来自“Device”类的设备对象,使用静态方法“searchObject”来定位设备对象。对于多个设备对象,它提供了“DeviceArray”类(从 Array 继承的子类)。DeviceArray 对象中的设备将同时执行相同的任务。
Device 类提供近 100 个方法和属性来操作设备。DeviceArray 类提供了大约 20 个常用方法。请参考 {{JavaScript API 文档}} 查看所有方法。您可以轻松扩展 Device 和 DeviceArray(请参阅扩展 Device 和 DeviceArray)。
使用“Device.searchObject()”来定位创建的设备对象,设备对象的格式为“device@<10位数字>”。
// 返回一个设备对象
var mySamsung = Device.searchObject('Samsung-S9');
// 返回所有设备对象,DeviceArray
var allDevices = Device.searchObject(tcConst.DevAll);
// 返回属于同一组的设备对象,DeviceArray
var allGroupX = Device.searchObject(tcConst.DevGroup, 'first row');
var allGroupY = Device.searchObject(tcConst.DevGroup, 'second row');
// 将两个组合成一个更大的组,DeviceArray
var groupXY = allGroupX.concat(allGroupY);
由于 DeviceArray() 是 Array() 的子类,它继承了 Array 类的大部分方法,由于所有 TC 特定的方法都与 DeviceArray 绑定,如果你有一个数组,请使用“var ary = new DeviceArray().concat(ary)”将其转换为 DeviceArray。
// 这会失败,因为 Array 中没有“click”方法
vardevice=Device.getMain();
varary=[device];
ary.click(100,100);
//Thiswillwork
vardevice=Device.getMain();
varary=newDeviceArray(device);
ary.click(100,100); // or ary.clickSync("OK");
以下是一些示例:
// 点击设备名称为 "Samsung-S10" 的设备上的位置 (100,200)。
var device = Device.searchObject('Samsung-S10');
if (device) {
device.click(100,200); // or device.clickSync("Start");
}
var devices = Device.searchObject(tcConst.DevAll);
if (devices) {
devices.click(0.5, 0.5); // or device.clickSync("John");
}
目录和 Userlib.js
默认情况下,脚本目录位于 \Users\<用户名>\Documents\Scripts 目录下,您可以通过在主窗口中点击 "Script",选择 "Script List",并在顶部行更改目录。
在该目录下,您可以创建一个名为 "Userlib.js" 的文件,该文件将在脚本执行之前始终加载,您可以在其中包含常用函数、添加现有类的原型或引入第三方软件。
要调试 "Userlib.js",请使用 "Terminal",要重新加载 "Userlib.js",请点击底部右侧终端窗口的重新加载图标。
绝对坐标与相对坐标
对于 x、y 坐标,TC 提供了 "绝对" 和 "相对" 坐标(系统设置中显示的坐标会同时显示两种坐标),绝对坐标从 (0, 0) 到 (width – 1, height – 1),相对坐标通常是四位小数,从 (0, 0) 到 (0.9999, 0.9999)。将相对坐标乘以设备的宽度和高度将得到绝对坐标。坐标并非完美无缺,专业版支持 AAI,它使用 UI 元素中的文本来在运行时检索坐标。
扩展设备和设备阵列
JavaScript 的额外好处是可扩展性,您可以通过向类添加原型来扩展方法。假设您要为单个和多个设备创建一个名为"longPress"的方法,一种编写方法的方式如下:
Device.prototype.longPress=function(x,y){
varretval=this.click(x,y,tcConst.STATE_DOWN);
if(retval!=0){
returnretval;
}
delay(500);
returnthis.click(x,y,tcConst.STATE_UP);
}
DeviceArray.prototype.longPress=function(x,y){
for(leti=0;i<this.length;++i){
retval=this[i].longPress(x,y);
if(retval!=0){
returnretval;
}
}
return 0;
}
这个实现对于包含大量设备的 DeviceArray 效率不高,如果阵列中有 100 个设备,该方法可能需要长达 50 秒。
更好的方法是先向所有设备发送 STATE_DOWN,然后等待剩余的 500 毫秒。幸运的是,Device 和 DeviceArray(多个设备)引入了"sendAll"方法,它执行指定的方法并等待指定的时间。这样,执行时间几乎为 500 毫秒。由于 "sendAll" 在 Device 和 DeviceArray 中都可用,因此 Device 和 DeviceArray 的代码实现完全相同。
Device.prototype.longPress=function(x,y){
varretval=this.sendAll(Device.prototype.click,
[x,y,tcConst.STATE_DOWN],500);
if(retval!=0){
returnretval;
}
returnthis.sendAll(Device.prototype.click,[x,y,tcConst.STATE_UP]);
}
DeviceArray.prototype.longPress=Device.prototype.longPress;
"sendAll" 方法仅适用于成功返回 0 的方法。
脚本工具
Total Control 提供许多工具,点击 "Script" 将打开一个新窗口:
Terminal(终端):打开 Rhino + RingoJS 命令提示符,您可以在此进行测试或开发。点击右下方的按钮重新加载解释器和 Userlib.js。可以使用 load("filename.js") 来运行脚本。
脚本列表 ⇒ 路径:脚本默认路径,点击图标可更改为其他目录。
脚本列表 ⇒ JS 源文件:用于快速执行 JavaScript 文件,提供了一个简单的编辑器,可以快速修改或点击箭头键来执行脚本。
脚本列表 ⇒ 录制脚本:将设备上的操作记录到 Excel 文件中,Excel 文件还可以用于生成 JS 脚本或 JSON 文件(对于 REST API 可能有用)。没有 JavaScript 经验的用户可以使用此工具生成简单的脚本。
脚本列表 ⇒ 图片助手:从主设备屏幕内容生成 BMP 文件,该图像文件用于 seekImage(),它扩展了 BMP 文件以提供其他信息,如应用程序名称、活动、宽度和高度信息。seekImage() 将利用这些信息而无需提供大量参数。
脚本列表 ⇒ 颜色助手:从主设备加载屏幕内容(类似于图像助手),使用放大的颜色选择器选择颜色的 RGB 值,并生成 seekColor(),具有复杂参数。可以支持单个和多个颜色。
脚本列表 ⇒ UI 探测:打开 UI 探测窗口,点击截屏按钮捕获现有的主手机窗口,并允许用户使用查询语言选择 UI 元素。命令助手 窗口将为查询语言中的每个键提供帮助描述。
执行器(将更名为任务):创建一个任务,在各种条件下运行脚本,例如日期和时间、迭代次数、常规间隔或设备。任务执行的输出和结果将保存供查看。任务也可以通过 JS API 创建或更改。Runner 的执行将显示为任务。
检查:检查与脚本和引擎相关的各种内部变量。
AAI 将屏幕上的 UI 元素识别为对象,传统的 (x, y) 坐标方式将屏幕视为一个巨大的对象,因此需要使用图像/颜色查找和光学字符识别 (OCR) 来识别屏幕上的对象。
无障碍功能是一种将屏幕上的 UI 元素表示为底层节点的功能,一个节点包含许多属性,如文本/描述、尺寸、布尔属性(可点击、可编辑或可滚动)、底层类名等。文本/描述可以轻松访问(无需使用 OCR),尺寸(和可点击性)确保按钮可以在特定位置被点击,即使节点被移动到另一个位置也能有效。
一个节点可以表示一个 UI 元素(例如按钮)、一组 UI 元素或某些元素的布局。节点(元素、组或布局)可以通过节点 ID(用十六进制字符串表示)进行标识。我们将无障碍功能、TC 脚本框架和 UI Automator 库进行集成,以实现以下目标:
AAI 的最简单案例:
devices.inputTextSync([位置], "文本") // 输入文本,位置用于多个输入
devices.runAppSync(<包名>, [查询])
devices.restartAppSync(<包名>, [查询])
整个屏幕由许多节点组成,一个节点可以是最小的 UI 元素或许多节点的容器,有些节点是不可见的。整个屏幕是从单个根节点开始的树状结构。根据应用程序的复杂程度,一个屏幕可能包含50-300个节点。
由于用户只对节点的一个小子集感兴趣,挑战在于找到用户想要的正确节点并从中提取信息或执行操作。
如何找到节点是一个挑战?我们发明了一种查询语言来查找节点,FindNode 程序安装在每个设备上,查询语言将被执行以获取满足条件的节点,意图是将大量节点减少为一个或少数几个目标节点,用户可以获取信息或对节点应用操作。
例如:Java 中的 UI Automator 提供了 "UiSelector" 和 "BySelector" 在 UiDevice.findObject() 或 findObjects() 中定位节点,对于多个条件可能会很复杂:
new UiSelector().className("android.widget.TextView").text("OK")
我们创建了一个简单的查询语言,它更短且可移植,因为查询将发送到许多设备,上述代码可以用我们的查询语言重写为:
"C: android.widget.TextView&&T:OK"
AAI 项目包括以下内容:
查询
每个查询包含一个或多个 "<key>:<value>" 对,多个键可以使用 "&&" 作为分隔符添加。
每个节点由一个节点 ID 来标识。查询可以分为三个阶段:
查询执行后,找到的一个或多个节点将列在"ML"(匹配列表)中,可以在 ML 上应用一系列操作,这些操作可以是获取信息或对 ML 执行操作。
模板:
为 BQ 或 EQ 生成初始节点。
TP:all -所有节点
TP:more -除了以"Layout"结尾的节点外的所有节点
TP:basic -所有叶子节点(子节点数为零)
TP:reduced -优化"TP:more",返回屏幕上重要的节点
TP:anyText[,<min>[,<max>]] -具有特定长度的"text"内容的节点。
TP:anyDescription[,<min>[,<max>]] -具有特定长度的"description"内容的节点。
TP:textInput -从左上到右下排序的所有可编辑字段。
TP:findText,<text> -具有参数中的文本的节点,可以包含 "*" 和 "/…/"。
TP:line,top|bottom,<number> -返回位于可滚动节点之外的前/后节点。
TP:scrollable,<position> -滚动容器内的节点,对于多个可滚动节点,使用位置参数。
基本查询(BQ):
用于获取节点级别信息的查询,从 TP 中的每个节点将与 BQ 中的节点匹配(如果提供)以继续执行。
扩展查询(EQ):
这里的查询通常涉及多个节点。
扩展查询的顺序很重要,所有的扩展查询从左到右执行。允许具有相同键的命令。
对于 BQ,查询语法可以包含 "!" 表示非,">" 和 "<" 表示大于和小于,"*" 表示通配符匹配,"/<regexp>/" 表示正则表达式。它可以匹配包名、类名、资源ID、文本、描述、子节点数和输入类型。
FindNode 已安装在每个设备上(作为 Total Control 应用的一部分),它是唯一能识别查询语法的程序,它解析查询、定位节点并对找到的节点执行操作。FindNode 将复杂的 JavaScript 和 Total Control 的 CPU 利用率卸载到设备上,所有的搜索都在设备上进行。
device.sendAAi() 和 devices.sendAai() 是与 FindNode 直接通信的方式,可以向一个或多个设备发送 JS 对象,发送前会将其转换为 JSON 格式,返回值以 JS 对象格式返回。如果遇到错误,返回值为 null,lastError() 中包含错误消息。
一个简单的查询示例,用于获取型号名称的文本,使用 X 偏移 1(右侧):
>> device.sendAai({query:"T:Model name&&OX:1", action:"getText"})
{retval: 'Galaxy S10+'}
FindNode 甚至可以检测屏幕顶部/底部的固定图标:
>> device.sendAai({query:"TP:line,bottom,-1", action:"getText"})
{retval: ['Chats','Calls','Contacts','Notifications']}
以下 3 个命令都可以点击 "Calls" 文本:
>> device.sendAai({query:"TP:line,bottom,-1&&T:Calls", action:"click"})
{retval: true}
>> device.sendAai({query:"TP:line,bottom,-1&&IX:1", action:"click"})
{retval: true}
>> device.sendAai({query:"TP:line,bottom,-1&&T:Chats&&OX:1", action:"click"})
{retval: true}
点击 "Contacts" 图标:
>> device.sendAai({query:"TP:line,bottom,-1&&T:Contacts&&OY:-1", action:"click"})
{retval: true}
>> device.sendAai({query:"TP:line,bottom,-1&&IX:2", action:"click"})
{retval: true}
// 在屏幕上找到多个 "Contacts",IX:-1 是选择最后找到的节点
>> device.sendAai({query:"T:Contacts&&IX:-1&&OY:-1", action:"click"})
{retval: true}
请阅读 FindNode 用户指南获取完整信息。
同步 API
在版本 8 之前,所有的操作和移动命令都是异步的。当一个命令(如 device.click())返回时,意味着该命令已经传递给我们的移动代理进行执行,当命令返回时,很可能命令尚未执行,因此需要使用 sleep 来给予动作完成和屏幕刷新的时间:
device.click(100, 100); sleep(300);
这种情况可能发生在所有的操作和移动命令中,使得编码变得繁琐。UI Automator 包括同步命令和等待窗口更新的功能,当点击被按下时,窗口已经更新,很可能命令已经完成。所有同步命令的后缀为 "Sync"。所有的 "Sync" 命令都使用 AAI 标签而不是坐标:
runAppSync()
restartAppSync()
clickSync()
inputTextSync()
UiElement 和 UiElementArray 对象的方法
同步功能的一个缺点是命令完成所需的时间比异步命令长得多,这可能会减慢大量设备的脚本执行速度,我们已经解决了这个问题。
随后的版本将为所有的操作和移动函数提供同步功能。
AAI 脚本(AAIS)
我们还开发了一个小型脚本,利用 AAI 的能力进行自动化,目前在 WDM 和 MDCC 中可用(文件扩展名为 ".tst"),捕获和回放(带有对象选项)将生成该脚本。它还提供与 JavaScript 的无缝集成(包含在 "{}" 中)。
例如:
exec "teslaLib.js"
open "Tesla"
find "T:VIN:"
get "T:VIN:&&OX:1", "text"
{ saveVar("vin", getOutput().retval) }
get "T:/[0-9,]+ miles/", "text"
{ saveMileage(new Date(), loadVar("vin"), getOutput().retval) }
print "Done"
此脚本可以同时在多个设备上运行,可在任何屏幕尺寸上运行,"find" 命令会滚动屏幕,直到找到满足查询条件的元素。任何一行的失败都会停止脚本的执行。它提供了 AAIS 和 JavaScript API 的命令。
另一个示例:
{
var apps = ["Skype", "Whatsapp", "Telegram"];
var arguments = getArg();
var app = apps[0];
if (arguments.length > 0) {
var appNum;
if(isNaN(appNum = parseInt(arguments[0]))) {
throw "Need a number;"
}
if (appNum < 1 || appNum > apps.length) {
throw "Option out of range";
}
app = apps[appNum-1];
}
}
open "${app}"
print "${app} opened"
请阅读 AAIS 用户指南 以获取有关 AAIS 的更多信息。
多设备控制中心(MDCC)
在 Total Control 的主窗口点击“多控中心”图标,进入多控中心.
更多内容将很快提供
设备控制设备组(DC)
该文章将很快提供。
支持
请发送电子邮件至 support@sigma-rt.com 以获得支持和反馈。