使用无障碍技术实现自动化脚本
Android 系统原生提供 AccessibilityService 无障碍服务设计初衷是为视障、行动不便用户提供屏幕朗读、快捷操作等辅助能力该服务拥有读取页面 UI 树、模拟触控、监听窗口与通知事件等系统级能力是移动端轻量化自动化最合规、门槛最低的技术路线无需 Root 设备仅需用户手动开启无障碍权限即可运行。不同于坐标点击、OCR 图像识别等视觉类自动化方案无障碍方案依托页面控件固有属性定位元素不受手机分辨率、APP 界面配色、字体大小影响多机型兼容性更强是日常任务自动化、APP 功能测试、重复操作替代场景的首选方案。本文从基础原理、核心 API 解析、完整脚本案例、避坑优化方案四个维度系统讲解无障碍自动化脚本开发流程面向普通脚本开发者、移动端测试人员不涉及商业推广聚焦技术落地与最佳实践。一、无障碍核心基础node 控件对象与 UI 树体系冰狐所有无障碍操作都围绕node控件对象展开手机屏幕上每一个按钮、输入框、文字、图片在系统 UI 树中都会生成独立 node 节点节点之间存在父子、兄弟层级关系这是控件定位与操作的底层依据。一node 核心属性解析每个 node 对象内置一套完整属性用于判断控件状态、获取位置信息也是findView定位控件的核心匹配条件关键属性分为四类文本与标识属性id控件资源 ID、text显示文本、className控件类名三者是定位控件最常用标识支持模糊匹配规则如txt*包含文本、id$ID 后缀匹配。交互状态属性clickable是否可点击、checked复选框选中状态、selected标签选中、enabled控件是否可用常用于循环判断控件交互状态。尺寸坐标属性left/top/right/bottom控件屏幕像素边界、width/height宽高可结合gestureClick实现精准坐标手势。层级关系属性parent父控件、prevSibling/nextSibling前后兄弟控件、数组下标直接访问子控件无唯一 ID / 文本的控件依靠层级定位。二UI 树调试工具使用方法开发脚本前必须借助平台 UI 树工具获取页面控件信息登录冰狐网页端进入「移动端 - 我的设备」选中在线设备点击获取 UI 树即可查看当前页面全部 node 节点右上角根索引可切换多根界面输入法、悬浮窗、状态栏均为独立根容器。 调试技巧无唯一标识的控件在 UI 树中记录目标控件的父、子层级索引后续通过family参数或数组下标精准抓取解决多同类型控件混淆问题。二、冰狐无障碍核心 API 分层详解冰狐将无障碍函数分为控件定位、页面交互、手势操作、页面流程控制、系统事件监听五大模块覆盖绝大多数自动化场景下文结合官方文档说明适用场景与典型代码示例。一控件定位类自动化脚本的核心根基定位是脚本稳定运行的关键findView是使用率最高的接口支持多条件组合、全局 / 局部根搜索、容错重试、筛选可点击控件等能力。findView按 tag 匹配控件tag 支持多匹配规则用|分隔或条件同时匹配options 参数提供find_all全量查找、traverse_invisible检索隐藏控件、root指定根容器缩小搜索范围failed回调可处理弹窗干扰。// 查找所有文本包含确认的可点击控件包含隐藏控件 var res findView(txt*:确认,{flag:find_all|clickable|traverse_invisible,maxStep:8,afterWait:300}); if(res.length0){ console.log(找到控件数量res.views.length); var targetBtn res.views[0]; }findRoot切换多根界面Android 页面存在多个根容器弹窗、键盘、悬浮窗直接全局搜索会出现控件找不到的问题findRoot可通过索引或文本定位目标根界面限定搜索范围。// 定位数字键盘弹窗根容器仅在弹窗内搜索输入按钮 var keyBoardRoot findRoot(txt:数字键盘); if(keyBoardRoot!null){ var numBtn findView(txt:5,{root:keyBoardRoot}); }family 层级定位无标识控件解决方案页面大量无独立 text、id 的装饰控件可先定位相邻唯一控件通过family数组层级索引跳转目标节点替代复杂的父子循环遍历简化代码。// 找到文本“设备名”控件取其父控件第0个子控件、第2个子控件 click(txt:设备名,{family:[0,2],click:true});二基础交互操作控件点击、输入、滚动click 控件点击支持原生控件点击click:true依赖控件 clickable 属性与手势模拟点击clickCount实现双击、长按widgetIndex指定点击第 N 个匹配控件适配列表批量操作。// 原生点击“提交”按钮点击后等待2秒加载页面 click(txt:提交,{click:true,afterWait:2000,maxStep:5});paste 文本输入统一处理输入框赋值type区分覆盖写入set与追加粘贴paste无需手动唤起键盘适配搜索框、表单填写场景。// 输入框写入测试文本 paste(cn:android.widget.EditText,自动化测试内容,{afterWait:500});scroll 页面滚动支持上下左右滑动type2调用系统翻页滑动更稳定distance控制滑动比例循环滚动列表遍历全部条目。// 列表向上滑动95%高度滑动后等待3秒加载数据 scroll(id:list_container,up,{type:2,distance:0.95,afterWait:3000});三底层手势与坐标操作当控件无法正常定位APP 限制无障碍读取节点可使用纯手势函数操作屏幕坐标支持单指、多指、自定义轨迹滑动gestureClick 单点坐标点击支持 px 像素、percent 屏幕比例单位适配不同分辨率设备multiGestureClick 多点同步点击模拟双指缩放、多按钮同时点击gesture 自定义轨迹手势可设置每段滑动时长模拟真人缓慢滑动降低风控识别概率。// 屏幕比例点击屏幕中心位置 gestureClick(0.5,0.5,{unit:percent,duration:150});四页面流程封装函数简化多步骤跳转针对页面切换、返回上一页等重复逻辑平台封装高集成度函数减少重复判断代码switchPage 单页面跳转点击查找控件校验目标页面标识判断是否跳转成功内置重试机制switchPages 批量连续切换一次性执行多页面跳转流程返回成功步骤数适合多级菜单导航back2Page 返回指定页面循环调用返回键直到页面出现目标控件适配弹窗、多级详情页返回场景。五系统监听回调函数事件驱动自动化区别于定时循环脚本cbNotification通知回调、cbWindowChange窗口变化回调实现事件触发式自动化资源占用更低适合消息响应类场景cbNotification系统收到 APP 通知自动触发可调用openNotification跳转通知详情cbWindowChange页面跳转、弹窗弹出、Toast 提示时触发实时捕获界面文本自动拦截广告弹窗。三、完整实战脚本APP 表单自动填写流程结合上述 API编写一套通用表单自动化脚本包含页面跳转、滚动查找、文本输入、提交、返回首页全流程包含容错、弹窗处理逻辑可直接修改 tag 适配各类 APPfunction main(){ // 步骤1进入我的页面 var enterMine switchPage(txt:我的,txt:设置,{maxStep:5,afterWait:1000}); if(enterMine.length0){ console.log(进入我的页面失败脚本终止); return; } // 步骤2滚动页面找到表单入口 scroll(null,up,{distance:0.8,afterWait:1000}); var formBtn findView(txt:表单填写,{flag:clickable,maxStep:6}); if(formBtn.length0){ back(); return; } click(formBtn.views[0],{click:true,afterWait:1500}); // 步骤3定位输入框并填写内容 var inputBox findView(cn:android.widget.EditText); if(inputBox.length0){ paste(inputBox.views[0],测试自动化表单,{type:set}); } // 步骤4勾选复选框 var checkBox findView(txt:同意协议); if(checkBox.length0 !checkBox.views[0].checked){ click(checkBox.views[0],{click:true}); } // 步骤5提交表单 click(txt:提交,{click:true,afterWait:2000}); // 步骤6返回首页 back2Page(txt:首页,{maxStep:10}); console.log(表单自动化流程执行完成); } // 窗口变化监听弹窗自动关闭 function cbWindowChange(textList,className,packageName,rawEvent){ if(textList.includes(广告)){ var closeBtn findView(txt:关闭,{maxStep:2}); if(closeBtn.length0) click(closeBtn.views[0]); } }四、无障碍脚本开发常见问题与优化实践一控件定位失败的解决办法页面存在多根界面使用findRoot切换弹窗、键盘根容器限定 root 搜索范围控件隐藏未检索findView添加traverse_invisible标识检索不可见控件同文本多个控件搭配family层级定位、widgetIndex指定下标、region限定屏幕区域缩小匹配范围APP 屏蔽无障碍节点降级使用gestureClick坐标手势作为兜底方案。二脚本稳定性优化方案增加等待参数所有操作添加beforeWait/afterWait适配 APP 加载动画避免页面未渲染完成查找控件配置重试机制findView设置maxStep自动重复搜索无需手动写循环弹窗自动拦截利用findView的failed回调或cbWindowChange全局监听自动关闭广告、权限弹窗拟人化操作click开启随机点击坐标、gesture设置滑动时长避免固定机械操作触发 APP 风控。三无障碍服务使用边界与合规提示Android 无障碍服务原生定位是辅助残障用户开发自动化脚本仅可用于个人自用、企业内部 APP 功能测试等合规场景禁止用于批量营销、违规引流、破解 APP 限制等违反应用服务协议与法律法规的场景。同时新版 Android 系统对无障碍权限管控持续收紧部分金融、社交 APP 会限制无障碍读取 UI 节点此类场景可搭配 OCR 图像识别作为补充方案。五、结语相比于坐标点击、图像识别无障碍自动化具备跨设备通用、运行稳定、资源消耗低三大优势是移动端轻量自动化的最优技术路线。开发者在实际编写脚本时应遵循 “优先控件属性定位、层级定位兜底、坐标手势作为最后备选” 的开发原则配合页面等待、弹窗容错逻辑大幅提升脚本长期挂机运行的可靠性。同时持续关注 Android 系统无障碍权限更新规则合理、合规使用无障碍能力规避应用限制与系统权限管控带来的脚本失效问题。

相关新闻