如何使用无障碍技术实现自动化脚本?
Android 无障碍技术能快速实现移动端 APP 的自动化操作,广泛适用于日常操作自动化、重复任务批量处理等场景。本文将从技术基础、核心流程、实战开发三个维度,详细讲解如何使用无障碍技术编写自动化脚本。
一、无障碍自动化的技术基础
1.1 核心运行环境
冰狐智能辅助的自动化脚本基于标准 ECMAScript 的自研子集开发,剔除了复杂的语法特性,保留了核心的变量、函数、流程控制等能力,同时针对移动端自动化做了大量定制化扩展。该脚本环境支持多线程并发、在线编辑、动态部署立即生效,且兼容标准 JavaScript 函数库,让开发者可以复用基础的 JS 开发经验。
1.2 无障碍技术的封装逻辑
Android 原生无障碍技术需要开发者处理大量的控件遍历、事件监听、手势模拟等底层逻辑,而冰狐智能辅助将这些逻辑封装为高内聚的 API 函数(如findView控件查找、click控件点击、scroll页面滚动等),开发者只需通过简单的 API 调用,就能实现对 APP 控件的精准操作,无需关注底层无障碍服务的实现细节。
1.3 脚本的核心特性
冰狐自研 JS 脚本为无障碍自动化做了多项专属优化,核心特性包括:
- 变量必须先声明后使用,提升脚本可读性和稳定性;
- 支持
__global/__permanent/__day专属变量,实现多模块、多线程的数据通信和持久化存储; - 强制要求分支、循环语句的子语句使用
{}包裹,避免语法歧义; - 内置系统事件回调(如通知监听
cbNotification、窗口切换cbWindowChange),可响应设备的实时状态变化; - 提供以
rs开头的系统内置常量(如rsScreenWidth屏幕宽度、rsDensity屏幕密度),快速获取设备和界面信息。
二、无障碍自动化脚本开发的核心流程
使用冰狐智能辅助开发无障碍自动化脚本,遵循环境准备→控件分析→脚本编写→调试运行的标准化流程,其中控件分析是无障碍自动化的核心,所有操作都基于对 APP 控件的精准定位。
2.1 前期环境准备
- 开启冰狐智能辅助的无障碍服务:在 Android 设备的「设置→无障碍」中,开启冰狐智能辅助的权限,这是脚本实现控件操作的基础;
- 开启设备的USB 调试(可选):如需电脑端调试,可开启 USB 调试,通过冰狐客户端连接设备;
- 熟悉冰狐的UI 树获取功能:在冰狐客户端「移动端→我的设备」中,点击目标设备的「获取 UI 树」,可实时查看当前 APP 页面的所有控件信息(包括控件 id、text、className、坐标等),为控件定位提供依据。
2.2 关键控件分析
无障碍自动化的本质是对 APP 控件的定位与操作,冰狐通过tag标识来定位控件,核心的tag前缀包括:
txt::按控件文本精确匹配,如txt:我的匹配文本为「我的」的控件;txt*::按控件文本模糊匹配,如txt*:x信匹配文本包含「x信」的控件;id::按控件 ID 精确匹配,如id:com.tencent.mm:id/tab_wechat;cn::按控件类名匹配,如cn:android.widget.EditText匹配输入框控件。
通过「获取 UI 树」功能获取目标控件的text、id或className后,即可通过冰狐的findViewAPI 精准定位控件,为后续的点击、输入、滚动等操作铺路。
2.3 脚本编写的通用规范
- 脚本的入口函数为
main,冰狐会自动执行该函数,外部可向其传递参数,返回值为脚本的执行结果; - 所有 API 调用需遵循冰狐的参数规范,如可选参数以 JSON 对象传递,默认值可省略;
- 对控件操作的结果做判空处理,如
findView查找控件后,需判断返回值的length是否大于 0,避免控件不存在导致脚本崩溃; - 合理使用
afterWait/beforeWait参数,为 APP 页面加载、控件渲染预留时间,提升脚本的稳定性。
2.4 调试与运行
冰狐支持在线调试和直接运行两种模式:
- 调试模式:可逐行执行脚本,查看
console.log的输出信息,定位脚本中的错误; - 运行模式:直接执行完整脚本,脚本在后台运行,实现自动化操作;
- 关键调试技巧:通过
console.log打印控件信息、API 返回值,排查控件定位失败、操作无效等问题。
三、核心无障碍 API 详解
冰狐智能辅助封装了近 20 个无障碍核心 API,覆盖APP 启动、控件定位、控件操作、页面导航、手势模拟等自动化全流程,以下为最常用的核心 API,所有参数均遵循冰狐官方规范。
3.1 APP 启动:launchApp
用于启动指定的 APP,通过包名和控件 tag 匹配确认启动成功,返回 1 表示成功,其他值表示失败。参数:包名(string)、匹配 tag(string)、可选配置(JSON,如maxStep重试次数、afterWait等待时间)。示例:launchApp('com.tencent.mm', 'txt*:x信', {maxStep: 40, afterWait: 2000})(启动x信,最多重试 40 次,启动后等待 2 秒)。
3.2 控件定位:findView
无障碍自动化的核心 API,通过tag查找目标控件,返回包含tag和views的 JSON 对象,views为找到的控件(node 对象)数组。核心参数:tag(控件标识)、options(可选配置,如flag:find_all查找所有匹配控件、root指定搜索根控件)。关键注意:若未找到控件,返回值的length为 0;找到的控件需通过ret.views[0]获取,而非ret[0]。
3.3 控件点击:click
对定位到的控件执行点击操作,支持原生点击和手势模拟点击,返回布尔值表示操作是否成功。核心参数:控件 tag / 节点对象、options(如click:true使用原生点击、clickCount:2双击、afterWait点击后等待时间)。
3.4 文本输入:paste
向输入框控件中设置或粘贴文本,支持set(直接设置)和paste(粘贴)两种模式,返回布尔值表示操作是否成功。核心参数:控件 tag / 节点对象、输入文本(string)、options(如type:'set'设置文本)。
3.5 页面滚动:scroll
模拟页面滚动操作,支持上下左右四个方向,可指定滚动距离和时长,返回布尔值表示操作是否成功。核心参数:滚动参考控件(null 表示整个屏幕)、滚动方向(up/down/left/right)、options(如distance滚动距离比例、duration滚动时长)。
3.6 页面导航:switchPage/back2Page
switchPage:点击指定控件并验证目标控件是否出现,实现页面切换的精准校验,返回值length>0表示切换成功;back2Page:多次调用返回键,直到找到目标控件,实现快速返回指定页面。
3.7 系统事件回调:cbNotification/cbWindowChange
无需主动调用,系统触发对应事件时自动执行:
cbNotification:设备收到通知(如x信消息、短信)时触发,可获取通知文本、包名等信息;cbWindowChange:APP 窗口切换、页面跳转时触发,可实时监听界面状态变化。
四、实战开发:x信自动发消息无障碍自动化脚本
以下以x信向指定好友发送消息为例,编写完整的无障碍自动化脚本,全程仅使用冰狐原生 JS API,包含 APP 启动、控件定位、页面切换、文本输入、消息发送全流程,附详细注释和关键要点说明。
4.1 脚本需求分析
- 启动x信 APP,确认启动成功;
- 在x信首页点击目标好友「张三」,进入聊天页面;
- 在输入框中输入文本「你好,这是冰狐自动化脚本发送的消息」;
- 点击「发送」按钮,完成消息发送;
- 对每一步操作做结果判空,确保脚本稳定性;
- 打印关键执行日志,方便调试。
4.2 前置控件分析
通过冰狐「获取 UI 树」功能,获取x信关键控件的标识:
- x信首页好友「张三」:文本匹配
txt:张三; - 聊天页面输入框:类名匹配
cn:com.tencent.mm.ui.widget.MMEditText; - 发送按钮:文本匹配
txt:发送。
4.3 完整 demo 源码
// x信自动发消息自动化脚本 - 冰狐智能辅助无障碍API实现 // 入口函数:main,冰狐自动执行 function main() { // 1. 定义全局常量,方便后续修改 var __global WX_PACKAGE = 'com.tencent.mm'; // x信包名 var __global TARGET_FRIEND = 'txt:张三'; // 目标好友tag var __global INPUT_BOX = 'cn:com.tencent.mm.ui.widget.MMEditText'; // 输入框tag var __global SEND_BTN = 'txt:发送'; // 发送按钮tag var __global SEND_CONTENT = '你好,这是冰狐自动化脚本发送的消息'; // 发送内容 // 2. 启动x信APP console.log('开始启动x信...'); var launchRet = launchApp(WX_PACKAGE, 'txt*:x信', {maxStep: 40, afterWait: 3000}); if (1 != launchRet) { console.log('x信启动失败,退出脚本'); return; // 启动失败,直接退出 } console.log('x信启动成功,进入首页'); // 3. 查找并点击目标好友「张三」,进入聊天页面 console.log('开始查找目标好友:张三'); var friendRet = findView(TARGET_FRIEND, {afterWait: 2000}); if (friendRet.length <= 0) { console.log('未找到好友张三,退出脚本'); return; } // 点击好友控件,使用原生点击,点击后等待3秒(页面加载) click(friendRet.views[0], {click: true, afterWait: 3000}); console.log('成功进入与张三的聊天页面'); // 4. 查找输入框,输入指定内容 console.log('开始查找输入框并输入内容'); var inputRet = findView(INPUT_BOX, {afterWait: 2000}); if (inputRet.length <= 0) { console.log('未找到聊天输入框,退出脚本'); return; } // 向输入框设置文本,设置后等待2秒 var pasteRet = paste(inputRet.views[0], SEND_CONTENT, {type: 'set', afterWait: 2000}); if (!pasteRet) { console.log('文本输入失败,退出脚本'); return; } console.log('文本输入成功,内容:' + SEND_CONTENT); // 5. 查找并点击发送按钮,发送消息 console.log('开始查找发送按钮并发送消息'); var sendRet = findView(SEND_BTN, {afterWait: 2000}); if (sendRet.length <= 0) { console.log('未找到发送按钮,退出脚本'); return; } // 点击发送按钮,使用原生点击,点击后等待3秒 click(sendRet.views[0], {click: true, afterWait: 3000}); console.log('消息发送成功!'); // 6. 脚本执行完成,返回桌面 home(); console.log('脚本执行完毕,已返回桌面'); } // 可选:添加窗口切换回调,监听页面状态变化 function cbWindowChange(textList, className, packageName, rawEvent) { console.log('【窗口切换】包名:' + packageName + ',当前页面文本:' + textList); } // 可选:添加通知监听,接收x信消息通知 function cbNotification(textList, className, packageName, rawEvent) { if (packageName == 'com.tencent.mm') { console.log('【x信通知】收到消息:' + textList); } }4.4 脚本核心要点说明
- 全局变量使用:通过
__global声明全局变量,将x信包名、控件 tag、发送内容抽离,方便后续修改和多线程共享; - 结果判空处理:每一步
findView/launchApp/paste后都做结果校验,避免控件不存在或操作失败导致脚本崩溃; - 等待时间合理设置:通过
afterWait为 APP 页面加载(如启动x信、进入聊天页面)预留时间,适配不同设备的运行速度; - 原生点击优先:设置
click: true使用控件原生点击功能,比手势模拟点击更精准,避免坐标偏移导致的点击无效; - 事件回调扩展:添加
cbWindowChange和cbNotification回调,实时监听页面切换和x信通知,可基于此实现更复杂的自动化逻辑(如收到消息自动回复); - 日志打印:通过
console.log打印每一步的执行状态,方便调试时定位问题。
五、无障碍自动化脚本的优化技巧
5.1 提升控件定位的精准性
- 优先使用控件 ID定位(
id:),ID 具有唯一性,比文本(txt:)更稳定,避免 APP 更新后文本变化导致定位失败; - 当控件无唯一 ID / 文本时,使用
@组合多条件匹配,如findView('txt:发送@cn:android.widget.Button'),匹配文本为「发送」且类名为按钮的控件; - 使用
root参数指定搜索根控件,缩小搜索范围,提升定位效率,如findView('txt:发送', {root: chatRoot})(仅在聊天页面根控件中搜索发送按钮)。
5.2 提升脚本的稳定性
- 合理设置
maxStep参数,为控件查找、APP 启动添加重试机制,如findView('txt:张三', {maxStep: 10}),最多重试 10 次; - 避免硬编码坐标,优先使用控件操作而非手势坐标点击(
gestureClick),适配不同分辨率的设备; - 对可能出现的弹窗(如x信的更新提示),使用
findView的failed参数添加异常处理,如failed: function(){click('txt:取消')}; - 使用
rs系统常量适配设备,如通过rsScreenWidth/rsScreenHeight计算相对坐标,实现跨设备兼容。
5.3 复杂场景的处理
- 连续页面切换:使用
switchPagesAPI 替代多次switchPage,实现多步骤页面切换的批量处理,如switchPages([['txt:我的', 'txt:设置'], ['txt:通用', 'txt:字体大小']]); - 多点手势操作:使用
multiGestureClick实现多点同时点击,gesture实现滑动、放大 / 缩小等复杂手势,如地图缩放、图片滑动; - 后台运行与事件响应:通过系统事件回调(
cbNotification/cbWindowChange)实现脚本的后台触发,如收到x信通知自动回复、检测到指定页面自动执行操作。
六、注意事项
- 无障碍权限保持开启:若关闭冰狐的无障碍服务,脚本将无法执行任何控件操作,需确保权限始终开启;
- 避免频繁操作:过度频繁的自动化操作可能被 APP 判定为异常行为,建议在操作之间添加合理的等待时间;
- 适配 APP 版本:APP 更新后可能会修改控件的 ID、类名或页面结构,需重新获取 UI 树,调整控件
tag;
七、总结
本文从技术基础、核心流程、API 详解到实战开发,完整讲解了无障碍自动化脚本的开发方法,实战 demo 覆盖了 APP 启动、控件操作、页面导航等核心场景,可作为后续开发的基础模板。在实际开发中,只需根据具体需求,通过「获取 UI 树」分析目标控件,结合冰核心 API 进行组合调用,再通过合理的异常处理和优化技巧提升脚本稳定性,即可实现绝大多数移动端 APP 的自动化操作。
