Android 自动化脚本编写指南
Android 自动化脚本编写指南1.0.17 版本环境搭建1、python安装 https://juejin.cn/post/73980465138109645202、工具安装 https://www.yuque.com/codeskyblue/uiautodev/usage3、adb安装 https://www.cnblogs.com/slgkaifa/p/191499954、安装Shizukuhttps://www.pgyer.com/shizuku-android-z5、执行脚本http://49.233.189.94:8888/down/yeMCXrJ0vwDR.js工具下载https://www.pgyer.com/automation程序逻辑一个脚本由多个步骤组成这些步骤都是线性的相当于工程的一条流水线。流水线由一个个步骤组成每个步骤由发现操作验证组成。当然一个环节中有可能都包含发现操作验证这也是相当于模拟人的操作也有可能只有一个或者两个这要看具体需求。前置的一些说明在一个脚本中维系这一个存储字典用于保存查找到的元素信息以及保存操作结果。都是通过saveKey保存通过getSaveKey获取。等待时间在任何一个环节执行前都有一个等待时间默认是1000-2000毫秒之间可以通过findWaitTimeactionWaitTimeverifyWaitTime配置。retryCount来配置重试次数。当前步骤执行几率chance0 ~ 1.0,如果不填写就是1.0必然执行发现环节通过findConditionBody配置查找元素可以多条件查询。findConditionBody:{saveKey:保存值的key,dataType:1: 普通数据, 2: 节点信息,conditions:[{type:id,value:com.zhiliaoapp.musically:id/dq4,logic:and},{type:text,value:^Allow$,logic:and,isRegular:true}]}type说明idid查找text通过文本查找className通过类名查找desc通过描述查找hint通过输入框占位提示hint查找packageName通过包名查找imageMatch通过图片匹配查找通用参数适用于 text、desc、hint参数必填默认值说明isRegular否false为true时value 按正则表达式匹配为false时text 完全匹配desc/hint 支持完全匹配或包含匹配规则说明textisRegularfalse时完全匹配isRegulartrue时 value 作为正则匹配节点文本中任意子串descisRegularfalse时完全匹配或包含isRegulartrue时 value 作为正则hintisRegularfalse时完全匹配或包含isRegulartrue时 value 作为正则正则示例// 完全匹配 Allow不匹配 Allow me、Allowance{type:text,value:^Allow$,logic:and,isRegular:true}// 包含匹配等价于 isRegularfalse 时的 contains{type:text,value:Allow,logic:and,isRegular:true}// 多选匹配{type:text,value:Allow|OK|允许,logic:and,isRegular:true}这里获取的元素会是一个或者多个但不管是一个还是多个。我们都将保存为数组。图片匹配查找功能说明通过图片匹配技术在屏幕上查找指定图片的位置适用于无法通过ID、文本等常规方式定位的元素。使用示例{findConditionBody:{saveKey:matched_image,conditions:[{type:imageMatch,value:https://example.com/template.png,logic:and}]}}参数说明type: 固定为 “imageMatch”value: 模板图片的URL地址logic: 逻辑关系and/or返回数据保存为ContextData对象数据类型为RECT包含匹配到的图片在屏幕上的矩形坐标信息操作环节注意如果你们找到的输入框不是 EditText的时候那么脚本必须运行在Android 13 及以上操作环节通过actionInfoBean配置操作元素可以多条件操作。actionInfoBean:{actionType:7,params:{packageName:com.zhiliaoapp.musically}},actionType操作名称说明1点击元素点击指定元素2长按元素长按指定元素3点击坐标点击指定坐标位置4长按坐标长按指定坐标位置5输入文本向输入框输入文本6滑动操作在屏幕上执行滑动操作7跳转应用跳转到指定应用8返回操作模拟按下返回键9退出应用退出当前应用10截图操作执行截图操作11获取元素信息获取指定元素的信息12保存文本保存文本数据13AI图片分析用于千问大模型进行图片内容分析14文件下载将文件下载到系统「下载」目录可选刷新相册15获取邮箱信息通过 IMAP 连接邮箱获取验证码等邮件内容params 是根据 actionType 来定义的不同操作类型对应不同的参数结构。以下是各操作类型的 params 说明actionType操作名称params 参数结构1点击元素{offset: 30,isAdbAction:false}br- offset: 随机点击范围半径像素, isAdbAction: 是否使用adb点击默认false2长按元素{offset: 30, duration: 1000}br- offset: 随机点击范围半径像素br- duration: 长按持续时间毫秒3点击坐标{x: 100, y: 200, offset: 10,isAdbAction:false}br- x: 点击X坐标br- y: 点击Y坐标br- offset: 随机点击范围半径像素br, isAdbAction: 是否使用adb点击默认false4长按坐标{x: 100, y: 200, offset: 10, duration: 1000}br- x: 长按X坐标br- y: 长按Y坐标br- offset: 随机点击范围半径像素br- duration: 长按持续时间毫秒5输入文本{text: 要输入的文本}br- text: 要输入的文本内容优先级最高当text不为空时使用br或{getSaveKey: savedText, isRandomGetListValue: false}br- getSaveKey: 从上下文获取数据的keybr- isRandomGetListValue: 是否随机获取列表中的值false取第一个true随机取6滑动操作{startX: 734, startY: 1705, startOffset: 80, endX: 909, endY: 740, endOffset: 80, slideDuration: 450}br- startX: 起始X坐标br- startY: 起始Y坐标br- startOffset: 起始点偏移像素br- endX: 结束X坐标br- endY: 结束Y坐标br- endOffset: 结束点偏移像素br- slideDuration: 滑动持续时间毫秒7跳转应用{packageName: com.zhiliaoapp.musically,versionName: 1.0.0}br- packageName: 目标应用包名8返回操作无参数9退出应用无参数10截图操作{left: 0, top: 0, width: 0, height: 0, saveKey: screenshotPath}- left/top/width/height: 截图区域均为 0 表示全屏saveKey: 截图路径保存到上下文的键名可选11获取元素信息{type: 1, saveKey: elementInfo}- type: 信息类型1-文本2-坐标3-大小等saveKey: 保存键名12保存文本{saveKey: savedText, saveValue: 要保存的文本}或{saveKey: savedText, saveValueList: [文本1, 文本2]}- saveKey/saveValue/saveValueList列表优先级更高13AI图片分析{getSaveKey: 图片路径的key, promptText: 提示词, apiKey: 阿里千问apiKey, saveKeyList: [name,age]}- getSaveKey/promptText/apiKey/saveKeyList14文件下载{url: https://example.com/file.png, isRefreshAlbum: true}- url: 下载地址必填isRefreshAlbum: 是否刷新相册默认 false15获取邮箱信息{account: 邮箱, authCode: 授权码, server: imap服务器, port: 993, from: 发件人关键词, title: 主题关键词, rule: 正则, saveKey: 保存键, timeout: 10000}- 详见下方「获取邮箱信息」章节点击坐标增强功能说明点击坐标操作现在支持从上下文数据中获取坐标信息特别是与图片匹配功能配合使用。使用示例{actionInfoBean:{actionType:3,params:{x:0,y:0,offset:10}},getSaveKey:matched_image}工作原理当x和y都为 0 时会尝试从上下文获取坐标首先检查contextData是否为RECT类型如果是则使用矩形中心作为点击坐标否则从getSaveKey指定的上下文中获取坐标数据文件下载功能说明将指定 URL 的文件同步下载到系统「下载」目录用户可在「文件」-「下载」中看到并可选择刷新相册/媒体库使图片等文件在系统相册中立即可见。保存位置Android 10 及以上通过 MediaStore 写入系统「下载」目录无需用户授权。Android 9 及以下写入公共下载目录需应用具备存储权限用户需手动授权。使用示例{name:下载图片到系统下载目录并刷新相册,actionInfoBean:{actionType:14,params:{url:https://example.com/image.png,isRefreshAlbum:true}},actionWaitTime:{lowerLimit:2000,upperLimit:4000}}参数说明url必填文件下载地址支持 http/https。isRefreshAlbum可选默认 false为true时会在下载完成后通知系统扫描该文件相册/文件管理会很快显示新文件无需用户手动刷新。说明该步骤会阻塞直到下载完成或失败后才执行下一步。获取邮箱信息功能说明通过 IMAP 连接邮箱按发件人/主题筛选邮件用正则提取验证码并保存到上下文。适用于自动化流程中需要获取邮箱验证码的场景如注册、登录时填写验证码。使用流程通常先执行「点击发送验证码」步骤再执行本步骤。步骤会先等待timeout毫秒给平台发邮件的时间再连接邮箱获取最新匹配的验证码。使用示例{name:获取邮箱验证码,actionInfoBean:{actionType:15,params:{account:your_emailgmail.com,authCode:your_app_password,server:imap.gmail.com,port:993,from:noreply,title:验证码,rule:\\d{4,8},saveKey:verify_code,timeout:10000}}}参数说明参数必填说明account是邮箱账号authCode是邮箱授权码Gmail 需应用专用密码QQ/163 需在邮箱设置中开启 IMAP 并获取授权码server是IMAP 服务器地址port否端口号默认 993from否发件人过滤关键词部分匹配不填则不过滤title否邮件主题过滤关键词部分匹配不填则不过滤。标题不确定时可省略rule否提取验证码的正则表达式默认\d{4,8}48 位数字saveKey是验证码保存到上下文的键名后续步骤可通过getSaveKey获取timeout否首次获取前等待时间毫秒默认 1000010 秒。点击发送验证码后需等待邮件到达常见邮箱 IMAP 配置邮箱serverportGmailimap.gmail.com993QQ 邮箱imap.qq.com993163 邮箱imap.163.com993与输入步骤配合获取的验证码保存到saveKey后可通过actionType: 5输入文本的getSaveKey参数读取并填入输入框。TikTok 验证码正则示例TikTok 邮件中验证码在 “Your 6-digit code is” 之后建议使用(?Your 6-digit code is[^0-9]*)\\d{6}精确匹配 6 位验证码避免误匹配用户 ID 等数字。验证环节验证环节通过verifyConditionBody配置验证元素可以多条件验证。verifyConditionBody:{saveKey:input_node,dataType:2,conditions:[{type:id,value:com.zhiliaoapp.musically:id/dpl,logic:and}]}验证环节可以不写就代表不用验证这次步骤如果写了没通过后续步骤将不再执行。执行失败一次可以通过配置retryCount来配置重试次数。脚本文件整体结构自动化脚本采用 JSON 格式主要包含以下结构{name:脚本名称,description:脚本描述,chance:1.0,stepList:[{steps:[{name:点击视频节点,actionInfoBean:{actionType:1,params:{offset:30}}},{name:点赞,findConditionBody:{conditions:[{type:id,value:com.zhiliaoapp.musically:id/f4u,logic:and}]},actionInfoBean:{actionType:1,params:{offset:4}}},{name:返回,actionInfoBean:{actionType:8}}],loopCount:5,name:步骤名称,retryCount:3,findConditionBody:{saveKey:保存值的key,dataType:1: 普通数据, 2: 节点信息,conditions:[// 操作参数]},actionInfoBean:{actionType:操作类型,params:{// 操作参数}},verifyConditionBody:{saveKey:保存值的key,dataType:1: 普通数据, 2: 节点信息,conditions:[// 操作参数]},findWaitTime:{lowerLimit:等待时间下限,upperLimit:等待时间上限},actionWaitTime:{lowerLimit:等待时间下限,upperLimit:等待时间上限},verifyWaitTime:{lowerLimit:等待时间下限,upperLimit:等待时间上限}}]}循环说明当一个步骤配置了loopCount或steps时该步骤即为循环步骤。此时该步骤上的发现、操作、验证配置将不生效仅会按loopCount重复执行其下的steps子步骤用于执行重复操作。脚本加载方式本地脚本当FlowFactory.isNetGetScrip为 false 时从本地jsonScript/run.json加载脚本。网络脚本当FlowFactory.isNetGetScrip为 true 时通过接口拉取服务端下发的脚本内容并解析执行。脚本 JSON 中若出现未支持的actionType会报错并提示「未知的 actionType」。常见问题「ActionInfoBean 的 params 为空」或「未知的 actionType」表示某一步的actionType不在 115 范围内或服务端/本地 JSON 中该步的actionType写错请检查脚本中每一步的actionInfoBean.actionType与上表一致。文件下载后相册里看不到将对应下载步骤的params.isRefreshAlbum设为true下载完成后会自动通知系统扫描相册会更新显示。下载步骤是否需要用户点授权Android 10 及以上下载到系统「下载」目录不需要用户授权Android 9 及以下需要用户同意存储权限。获取邮箱信息失败或拿不到验证码Gmail需开启 IMAP并在 Google 账号中生成「应用专用密码」作为 authCode不能使用账号密码。QQ/163需在邮箱设置中开启 IMAP 服务获取授权码作为 authCode。若 10 秒后仍无匹配邮件可能是平台发信延迟或 from/title 过滤过严可适当增大 timeout 或放宽过滤条件。「无法获取当前窗口根节点」或 uiautomator dump 返回 Killed根节点间歇性为 null系统已做重试和 fallback多数情况可自动恢复。uiautomator dump 被 Killed多为设备内存不足OOM可关闭其他应用或重启设备dump 使用/sdcard/uidump.xml路径。