Android RPA 开发文档
RPA 有 Python 语言和 Go 语言两种 API 文档,下面将分别介绍两种语言使用方法。
MYT RPA SDK Python 语言 API 文档
该包封装了 libmytrpc.dll 中的所有功能,用于远程控制设备
📌 端口列表
- 更新日期 2025-04-07 初始版本
桥接模式
- IP 地址:桥接设备的 IP 地址
- RPA 端口:固定为 9083
非桥接模式
- IP 地址(如 192.168.30.2):用来定位具体的设备或宿主机
- RPA 端口:根据设备实例索引计算得出,计算公式为:30000 + (index - 1) × 100 + 2
Q1 设备端口列表(index 1-12):
| 实例位 | 实例位(index) | RPA 端口 |
|---|---|---|
| 坑位1 | 1 | 30002 |
| 坑位2 | 2 | 30102 |
| 坑位3 | 3 | 30202 |
| 坑位4 | 4 | 30302 |
| 坑位5 | 5 | 30402 |
| 坑位6 | 6 | 30502 |
| 坑位7 | 7 | 30602 |
| 坑位8 | 8 | 30702 |
| 坑位9 | 9 | 30802 |
| 坑位10 | 10 | 30902 |
| 坑位11 | 11 | 31002 |
| 坑位12 | 12 | 31102 |
P1 设备端口列表(index 1-24):
| 实例位 | 坑位号(index) | RPA 端口 |
|---|---|---|
| 坑位1 | 1 | 30002 |
| 坑位2 | 2 | 30102 |
| 坑位3 | 3 | 30202 |
| 坑位4 | 4 | 30302 |
| 坑位5 | 5 | 30402 |
| 坑位6 | 6 | 30502 |
| 坑位7 | 7 | 30602 |
| 坑位8 | 8 | 30702 |
| 坑位9 | 9 | 30802 |
| 坑位10 | 10 | 30902 |
| 坑位11 | 11 | 31002 |
| 坑位12 | 12 | 31102 |
| 坑位13 | 13 | 31202 |
| 坑位14 | 14 | 31302 |
| 坑位15 | 15 | 31402 |
| 坑位16 | 16 | 31502 |
| 坑位17 | 17 | 31602 |
| 坑位18 | 18 | 31702 |
| 坑位19 | 19 | 31802 |
| 坑位20 | 20 | 31902 |
| 坑位21 | 21 | 32002 |
| 坑位22 | 22 | 32102 |
| 坑位23 | 23 | 32202 |
| 坑位24 | 24 | 32302 |
目录结构
以下是 MYT RPA SDK 的完整目录结构,帮助您理解如何组织和使用 SDK 文件:
MYT_RPA_SDK_V10_20250407/
├── arm/ # ARM架构库文件(rk3588)
│ └── libmytrpc_arm.so # ARM Linux库
├── centos7/ # CentOS 7库文件
│ └── libmytrpc_centos.so # CentOS 7 Linux库
├── demo_py_x64/ # Python 64位演示项目
│ ├── rpc_demo.py # Python演示脚本
│ ├── common/ # 公共模块目录
│ │ ├── logger.py # 日志模块
│ │ ├── mytRpc.py # Python SDK核心实现
│ │ ├── mytSelector.py # 选择器实现
│ │ ├── rpcNode.py # 节点操作实现
│ │ ├── ToolsKit.py # 工具函数
│ │ └── __init__.py # 模块初始化
│ ├── lib/ # 库文件目录
│ │ ├── libmytrpc.dll # Windows库文件
│ │ ├── libmytrpc.dylib # macOS库文件
│ │ └── libmytrpc.lib # Windows导入库
│ └── log/ # 日志目录
├── include/ # 头文件目录
│ └── libmytrpc.h # C头文件
├── lib/ # Windows 32位库目录
│ ├── libmytrpc.dll # Windows 32位库文件
│ └── libmytrpc.lib # Windows 32位导入库
├── lib64/ # Windows 64位库目录
│ ├── libmytrpc.dll # Windows 64位库文件
│ └── libmytrpc.lib # Windows 64位导入库
├── macos(m)/ # macOS M系列芯片库目录
│ └── libmytrpc.dylib # macOS M系列库文件
├── macos(x86)/ # macOS x86芯片库目录
│ └── libmytrpc.dylib # macOS x86库文件
├── ubuntu/ # Ubuntu库目录
│ └── libmytrpc_ubuntu_x86_64.so # Ubuntu x86_64库文件
└── README.txt # SDK说明文档
引用文件功能与使用说明
模块导入
Python 版本采用面向对象的方式进行调用。以下是正确的导入方式:
# 导入核心SDK类
from common.mytRpc import MytRpc
# 选择器和节点类通常通过 MytRpc 方法间接获取,无需直接导入
依赖要求
- Python 3.7+ 64位版本
- Windows / Linux / macOS 操作系统
- 需要将对应平台的库文件放置在项目的
lib目录下 - 可选依赖:
- OpenCV (cv2):用于图像处理和显示
- NumPy (numpy):用于图像数据处理
引用文件功能说明
| 文件名 | 功能描述 | 主要方法/类 | 使用场景 |
|---|---|---|---|
mytRpc.py | 核心 SDK 实现,封装了与设备通信的所有主要功能 | MytRpc 类 | 所有设备控制操作的入口点 |
mytSelector.py | 提供 UI 元素选择器功能,用于查找和筛选 UI 节点 | mytSelector 类 | 需要根据条件查找 UI 元素时使用 |
rpcNode.py | 封装了 UI 节点的操作和属性获取方法 | rpcNode 类 | 获取节点属性、执行节点操作时使用 |
logger.py | 提供日志记录功能 | logger 对象 | 需要记录日志信息时使用 |
ToolsKit.py | 提供各种工具函数 | ToolsKit 类 | 获取程序路径、检查进程状态等工具操作 |
__init__.py | 模块初始化文件 | - | 确保 common 目录可作为 Python 模块导入 |
库文件说明
SDK 根据不同平台提供对应的底层库文件:
| 平台 | 文件 | 目录 |
|---|---|---|
| Windows 32位 | libmytrpc.dll / libmytrpc.lib | lib/ |
| Windows 64位 | libmytrpc.dll / libmytrpc.lib | lib64/ |
| macOS M系列 | libmytrpc.dylib | macos(m)/ |
| macOS x86 | libmytrpc.dylib | macos(x86)/ |
| CentOS 7 | libmytrpc_centos.so | centos7/ |
| Ubuntu x86_64 | libmytrpc_ubuntu_x86_64.so | ubuntu/ |
| ARM (rk3588) | libmytrpc_arm.so | arm/ |
SDK 会根据 sys.platform 自动选择对应的库文件加载。
安装 说明
-
复制库文件:从 SDK 包中复制对应平台的库文件到您项目的
lib目录:项目目录/
└── lib/
└── libmytrpc.dll # Windows库文件(或对应平台的库文件) -
复制Python模块:从
demo_py_x64/common/目录复制以下 Python 模块到您项目的common目录:mytRpc.py(核心SDK实现)mytSelector.py(选择器功能)rpcNode.py(节点操作)logger.py(日志功能)ToolsKit.py(工具函数)__init__.py(模块初始化)
-
项目结构:最终的项目结构应如下所示:
项目目录/
├── common/
│ ├── __init__.py
│ ├── logger.py
│ ├── mytRpc.py
│ ├── mytSelector.py
│ ├── rpcNode.py
│ └── ToolsKit.py
├── lib/
│ └── libmytrpc.dll # 对应平台的库文件
└── your_script.py # 您的Python脚本 -
在脚本中使用:
from common.mytRpc import MytRpc
mytapi = MytRpc()
if mytapi.init("设备IP", 端口号, 超时时间) == True:
print("连接成功")
目录
MytRpc 类 - 核心 SDK
MytRpc 类是 SDK 的核心类,负责与远程设备建立连接并提供所有设备控制功能。所有方法都是实例方法,无需传递 handle 参数——handle 在内部自动管理。
初始化与释放
MytRpc()
创建 MytRpc 实例,自动根据平台选择库文件路径。
mytapi = MytRpc()
SDK 会根据 sys.platform 自动选择对应的库文件:
- Windows:
项目根目录/lib/libmytrpc.dll - Linux:
项目根目录/lib/libmytrpc.so - macOS:
项目根目录/lib/libmytrpc.dylib
init
初始化并连接远程设备。内部会重试连接直到成功或超时。
def init(self, ip: str, port: int, timeout: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| ip | str | 要远程控制的设备的IP地址 |
| port | int | 要远程控制的设备的RPA端口 |
| timeout | int | 连接超时时间,单位秒。每10秒重试一次 |
返回值: bool - 连接成功返回 True,超时或失败返回 False
get_sdk_version
获取当前 SDK 的版本号
def get_sdk_version(self) -> str
返回值: str - 版本号字符串,如果库文件不存在则返回空字符串 ''
check_connect_state
检测远程连接是否处于连接状态
def check_connect_state(self) -> bool
返回值: bool - True 表示已连接,False 表示已断开
基础设备方法
setRpaWorkMode
设置RPA工作模式(无障碍模式开关)
def setRpaWorkMode(self, mode: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| mode | int | 工作模式(1: 开启无障碍[默认], 0: 关闭无障碍) |
返回值: bool - 设置成功返回 True,失败返回 False
说明:
- 开启无障碍模式后,可以获取更加完整的节点信息,但某些应用环境会检测是否开启了无障碍
- 该方法需要最新的固件版本支持
exec_cmd
执行shell命令
def exec_cmd(self, cmd: str) -> tuple[str, bool]
| 参数 | 类型 | 说明 |
|---|---|---|
| cmd | str | 要执行的命令行字符串 |
返回值: tuple[str, bool] - 返回元组 (output_text, success),output_text 为命令输出,success 为执行是否成功
dumpNodeXml
获取节点树数据(XML格式)
def dumpNodeXml(self, bDumpAll: int) -> str | bool
| 参数 | 类型 | 说明 |
|---|---|---|
| bDumpAll | int | 是否导出所有节点(0或1) |
返回值: str - 节点树XML字符串;失败时返回 False
dumpNodeXmlEx
获取节点树数据(扩展版本,支持设置工作模式和超时)
def dumpNodeXmlEx(self, workMode: bool, timeout: int) -> str | bool
| 参数 | 类型 | 说明 |
|---|---|---|
| workMode | bool | True 开启无障碍,False 关闭无障碍 |
| timeout | int | 超时时间,单位毫秒。-1为永不超时 |
返回值: str - 节点树XML字符串;失败时返回 False
getDisplayRotate
获取当前屏幕的旋转方向
def getDisplayRotate(self) -> bool
返回值: bool - 旋转方向为1时返回 True,否则返回 False
注意:当前实现仅检测旋转方向是否为1,如需获取完整旋转角度(0/1/2/3),需直接调用底层DLL。
截图方法
takeCaptrueCompress
远程截图,获取压缩后的图像字节数组
def takeCaptrueCompress(self, type: int, quality: int) -> bytearray | bool
| 参数 | 类型 | 说明 |
|---|---|---|
| type | int | 0表示PNG,1表示JPG |
| quality | int | 压缩质量,取值0-100 |
返回值: bytearray - 压缩后的图像数据;失败时返回 False
takeCaptrueCompressEx
远程截图(指定区域,压缩格式)
def takeCaptrueCompressEx(self, left: int, top: int, right: int, bottom: int, type: int, quality: int) -> bytearray | bool
| 参数 | 类型 | 说明 |
|---|---|---|
| left | int | 截图区域的左坐标 |
| top | int | 截图区域的上坐标 |
| right | int | 截图区域的右坐标 |
| bottom | int | 截图区域的下坐标 |
| type | int | 0表示PNG,1表示JPG |
| quality | int | 压缩质量,取值0-100 |
返回值: bytearray - 压缩后的图像数据;失败时返回 False
screentshot
截图并保存到文件
def screentshot(self, type: int, quality: int, file_path: str) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| type | int | 0表示PNG,1表示JPG |
| quality | int | 压缩质量,取值0-100 |
| file_path | str | 保存文件路径 |
返回值: bool - 成功返回 True,失败返回 False
screentshotEx
截图(指定区域)并保存到文件
def screentshotEx(self, left: int, top: int, right: int, bottom: int, type: int, quality: int, file_path: str) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| left | int | 截图区域的左坐标 |
| top | int | 截图区域的上坐标 |
| right | int | 截图区域的右坐标 |
| bottom | int | 截图区域的下坐标 |
| type | int | 0表示PNG,1表示JPG |
| quality | int | 压缩质量,取值0-100 |
| file_path | str | 保存文件路径 |
返回值: bool - 成功返回 True,失败返回 False
触摸操作方法
touchDown
模拟按下
def touchDown(self, finger_id: int, x: int, y: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| finger_id | int | 手指编号(0-9) |
| x | int | X坐标 |
| y | int | Y坐标 |
返回值: bool - 成功返回 True,失败返回 False
touchUp
模拟弹起
def touchUp(self, finger_id: int, x: int, y: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| finger_id | int | 手指编号(0-9) |
| x | int | X坐标 |
| y | int | Y坐标 |
返回值: bool - 成功返回 True,失败返回 False
touchMove
模拟移动
def touchMove(self, finger_id: int, x: int, y: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| finger_id | int | 手指编号(0-9) |
| x | int | X坐标 |
| y | int | Y坐标 |
返回值: bool - 成功返回 True,失败返回 False
touchClick
模拟单击
def touchClick(self, finger_id: int, x: int, y: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| finger_id | int | 手指编号(0-9) |
| x | int | X坐标 |
| y | int | Y坐标 |
返回值: bool - 成功返回 True,失败返回 False
longClick
模拟长按
def longClick(self, finger_id: int, x: int, y: int, t: float) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| finger_id | int | 手指编号(0-9) |
| x | int | X坐标 |
| y | int | Y坐标 |
| t | float | 长按时长,单位秒 |
返回值: bool - 成功返回 True,失败返回 False
swipe
模拟滑动
def swipe(self, id: int, x0: int, y0: int, x1: int, y1: int, elapse: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 手指编号(0-9) |
| x0 | int | 起始X坐标 |
| y0 | int | 起始Y坐标 |
| x1 | int | 结束X坐标 |
| y1 | int | 结束Y坐标 |
| elapse | int | 滑动持续时间(毫秒) |
返回值: bool - 操作结果
按键和文本输入方法
keyPress
模拟按键
def keyPress(self, code: int) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| code | int | 按键码 |
返回值: bool - 成功返回 True,失败返回 False
pressBack
模拟返回键(按键码 4)
def pressBack(self) -> bool
pressEnter
模拟回车键(按键码 66)
def pressEnter(self) -> bool
pressHome
模拟Home键(按键码 3)
def pressHome(self) -> bool
pressRecent
模拟最近任务键(按键码 82)
def pressRecent(self) -> bool
sendText
模拟键盘输入
def sendText(self, text: str) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| text | str | 要输入的字符串 |
返回值: bool - 成功返回 True,失败返回 False
ClearText
清除输入的文字(通过按退格键实现)
def ClearText(self, count: int) -> None
| 参数 | 类型 | 说明 |
|---|---|---|
| count | int | 要清除的字符数量 |
该方法通过连续按 KEYCODE_DEL (67) 实现,无返回值。
App操作方法
openApp
打开指定包名的app
def openApp(self, pkg: str) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| pkg | str | 包名 |
返回值: bool - 成功返回 True,失败返回 False
stopApp
停止指定的应用
def stopApp(self, pkg: str) -> bool
| 参数 | 类型 | 说明 |
|---|---|---|
| pkg | str | 包名 |
返回值: bool - 成功返回 True,失败返回 False
视频流方法
startVideoStream
启动屏幕视频流传输
def startVideoStream(self) -> bool
注意:当前实现使用硬编码参数(宽400,高720,比特率20000),成功启动后会进入无限循环。视频数据通过模块级回调函数
video_cb和audio_cb接收处理。
选择器方法
create_selector
创建一个筛选器对象
def create_selector(self) -> mytSelector | None
返回值: mytSelector - 筛选器对象;未连接时返回 None
release_selector
释放筛选器对象
def release_selector(self, sel: mytSelector) -> None
| 参数 | 类型 | 说明 |
|---|---|---|
| sel | mytSelector | 要释放的筛选器对象 |
便捷点击方法
以下方法封装了"创建选择器 → 设置条件 → 查找节点 → 点击"的完整流程,使用更简洁。
clickText
按照文本精确匹配查找节点并点击
def clickText(self, text: str) -> bool
clickTextMatchStart
按照文本前缀匹配查找节点并点击
def clickTextMatchStart(self, text: str) -> bool
clickClass
按照类名精确匹配查找节点并点击
def clickClass(self, clzName: str) -> bool
clickId
按照资源ID精确匹配查找节点并点击
def clickId(self, id: str) -> bool
clickDesc
按照描述精确匹配查找节点并点击
def clickDesc(self, des: str) -> bool
便捷节点查找方法
以下方法封装了"创建选择器 → 设置条件 → 查找节点 → 转JSON"的完整流程,返回JSON字符串。
getNodeByText
按照文本精确匹配查找节点
def getNodeByText(self, text: str) -> str | None
返回值: str - JSON字符串(数组格式),未找到返回 None
getNodeByTextMatchStart
按照文本前缀匹配查找节点
def getNodeByTextMatchStart(self, text: str) -> str | None
getNodeByTextMatchEnd
按照文本后缀匹配查找节点
def getNodeByTextMatchEnd(self, text: str) -> str | None
getNodeByPkg
按照包名精确匹配查找节点
def getNodeByPkg(self, pkg: str) -> str | None
getNodeByClass
按照类名精确匹配查找节点
def getNodeByClass(self, clzName: str) -> str | None
getNodeById
按照资源ID精确匹配查找节点
def getNodeById(self, id: str) -> str | None
getNodeByDesc
按照描述精确匹配查找节点
def getNodeByDesc(self, desc: str) -> str | None
mytSelector 类 - UI 元素选择器
mytSelector 类用于创建和管理 UI 元素选择条件,查找符合条件的 UI 节点。
通过 MytRpc.create_selector() 创建,支持 with 语句。
查询执行方法
execQuery
执行查询返回符合条件的 Node 结果集
def execQuery(self, maxNode: int, timeout: int, reset_query: bool = True) -> list[rpcNode]
| 参数 | 类型 | 说明 |
|---|---|---|
| maxNode | int | 期望最多筛选出的结果数量,超过直接返回 |
| timeout | int | 查找超时时间(毫秒),未找到会一直查找直到超时 |
| reset_query | bool | 查询完成后是否自动清除筛选条件,默认 True |
返回值: list[rpcNode] - 匹配的节点列表
execQueryOne
执行查询返回第一个匹配的 Node
def execQueryOne(self, timeout: int, reset_query: bool = True) -> rpcNode | None
| 参数 | 类型 | 说明 |
|---|---|---|
| timeout | int | 查找超时时间(毫秒),未找到会一直查找直到超时 |
| reset_query | bool | 查询完成后是否自动清除筛选条件,默认 True |
返回值: rpcNode - 第一个匹配的节点,未找到返回 None
clear_Query
清除所有筛选条件
def clear_Query(self) -> None
布尔属性筛选
| 方法名 | 参数 | 说明 |
|---|---|---|
addQuery_Enable(self, enable) | enable: int | 设置节点是否可用筛选器 |
addQuery_Checkable(self, enable) | enable: int | 设置节点是否可以被选中筛选器 |
addQuery_Clickable(self, enable) | enable: int | 设置节点是否可以被点击筛选器 |
addQuery_Focusable(self, enable) | enable: int | 设置节点是否可以获取焦点筛选器 |
addQuery_Foucesd(self, val) | val: int | 设置节点是否已经获取焦点筛选器 |
addQuery_Scrollable(self, enable) | enable: int | 设置节点是否可以滚动筛选器 |
addQuery_LongClickable(self, enable) | enable: int | 设置节点是否可以长按筛选器 |
addQuery_Passwordable(self, enable) | enable: int | 设置节点是否是密码筛选器 |
addQuery_Selectedable(self, enable) | enable: int | 设置节点是否被选中筛选器 |
addQuery_Visible(self, enable) | enable: int | 设置节点是否可见筛选器 |
注意:以上参数均为
int类型(0或1),非bool类型。addQuery_Foucesd方法名中 "Foucesd" 为代码中的拼写,实际对应底层的Focused属性。
边界筛选
| 方法名 | 说明 |
|---|---|
addQuery_BoundsInside(self, left, top, right, bottom) | 设置在节点指定范围内的筛选器 |
addQuery_BoundsEqual(self, left, top, right, bottom) | 设置节点的范围等于指定范围的筛选器 |
索引筛选
| 方法名 | 说明 |
|---|---|
addQuery_index(self, ids) | 设置节点索引筛选器 |
ID匹配筛选
| 方法名 | 说明 |
|---|---|
addQuery_IdEqual(self, str_id) | 设置节点的资源ID等于指定id的筛选器 |
addQuery_IdStartWith(self, str_id) | 设置节点的资源ID以指定字符串开头的筛选器 |
addQuery_IdEndWith(self, str_id) | 设置节点的资源ID以指定字符串结尾的筛选器 |
addQuery_IdContainWith(self, str_id) | 设置节点的资源ID包含指定字符串的筛选器 |
addQuery_IdMatchWith(self, str_id) | 设置节点的资源ID正则匹配指定字符串的筛选器 |
Text匹配筛选
| 方法名 | 说明 |
|---|---|
addQuery_TextEqual(self, text) | 设置节点文本等于指定字符串的筛选器 |
addQuery_TextStartWith(self, text) | 设置节点文本以指定字符串开头的筛选器 |
addQuery_TextEndWith(self, text) | 设置节点文本以指定字符串结尾的筛选器 |
addQuery_TextContainWith(self, text) | 设置节点文本包含指定字符串的筛选器 |
addQuery_TextMatchWith(self, text) | 设置节点文本正则匹配指定字符串的筛选器 |
Class匹配筛选
| 方法名 | 说明 |
|---|---|
addQuery_ClzEqual(self, text) | 设置节点类名等于指定字符串的筛选器 |
addQuery_ClzStartWith(self, text) | 设置节点类名以指定字符串开头的筛选器 |
addQuery_ClzEndWith(self, text) | 设置节点类名以指定字符串结尾的筛选器 |
addQuery_ClzContainWith(self, text) | 设置节点类名包含指定字符串的筛选器 |
addQuery_ClzMatchWith(self, text) | 设置节点类名正则匹配指定字符串的筛选器 |
Package匹配筛选
| 方法名 | 说明 |
|---|---|
addQuery_PackageEqual(self, text) | 设置节点包名等于指定字符串的筛选器 |
addQuery_PackageStartWith(self, text) | 设置节点包名以指定字符串开头的筛选器 |
addQuery_PackageEndWith(self, text) | 设置节点包名以指定字符串结尾的筛选器 |
addQuery_PackageContainWith(self, text) | 设置节点包名包含指定字符串的筛选器 |
addQuery_PackageMatchWith(self, text) | 设置节点包名正则匹配指定字符串的筛选器 |
Desc匹配筛选
| 方 法名 | 说明 |
|---|---|
addQuery_DescEqual(self, text) | 设置节点描述等于指定字符串的筛选器 |
addQuery_DescStartWith(self, text) | 设置节点描述以指定字符串开头的筛选器 |
addQuery_DescEndWith(self, text) | 设置节点描述以指定字符串结尾的筛选器 |
addQuery_DescContainWith(self, text) | 设置节点描述包含指定字符串的筛选器 |
addQuery_DescMatchWith(self, text) | 设置节点描述正则匹配指定字符串的筛选器 |
rpcNode 类 - UI 节点操作
rpcNode 类封装了 UI 节点的属性获取和操作方法。通过 mytSelector.execQuery() 或 execQueryOne() 获取。
树遍历方法
getParent
获取父节点
def getParent(self) -> rpcNode | None
返回值: rpcNode - 父节点,无父节点时返回 None
getChildCount
获取子节点数量
def getChildCount(self) -> int
返回值: int - 子节点数量
getChild
获取所有子节点
def getChild(self) -> list[rpcNode]
返回值: list[rpcNode] - 子节点列表
节点属性获取方法
getNodeJson
获取节点的JSON字符串
def getNodeJson(self) -> str
返回值: str - JSON字符串
getNodeText
获取节点的文本属性
def getNodeText(self) -> str
返回值: str - 文本内容
getNodeDesc
获取节点的描述属性
def getNodeDesc(self) -> str
返回值: str - 描述内容
getNodePackage
获取节点的包名属性
def getNodePackage(self) -> str
返回值: str - 包名
getNodeClass
获取节点的类名属性
def getNodeClass(self) -> str
返回值: str - 类名
getNodeId
获取节点的资源ID属性
def getNodeId(self) -> str
返回值: str - 资源ID
getNodeNound
获取节点的边界范围
def getNodeNound(self) -> dict
返回值: dict - {'left': int, 'top': int, 'right': int, 'bottom': int},获取失败时各值为 -1
注意:方法名 "Nound" 为代码中的命名,实际含义为 "Bound"(边界)。
getNodeNoundCenter
获取节点的中心坐标
def getNodeNoundCenter(self) -> dict
返回值: dict - {'x': int, 'y': int},获取失败时各值为 -1
节点操作方法
Click_events
点击节点
def Click_events(self) -> bool
返回值: bool - 成功返回 True,失败返回 False
longClick_events
长按节点
def longClick_events(self) -> bool
返回值: bool - 成功返回 True,失败返回 False
使用示例
基础使用示例
from common.mytRpc import MytRpc
def main():
mytapi = MytRpc()
# 获取SDK版本
sdk_ver = mytapi.get_sdk_version()
print(f"SDK版本: {sdk_ver}")
# 初始化并连接设备
# 注意:端口不是adb端口,计算公式为:30000 + (index - 1) × 100 + 2
if mytapi.init("192.168.1.100", 30202, 10) == True:
print("设备连接成功")
try:
# 检查连接状态
if mytapi.check_connect_state():
print("当前连接状态正常")
# 设置工作模式
mytapi.setRpaWorkMode(1) # 1=开启无障碍
finally:
pass
else:
print("设备连接失败")
if __name__ == "__main__":
main()
截图示例
from common.mytRpc import MytRpc
def main():
mytapi = MytRpc()
if mytapi.init("192.168.1.100", 30202, 10) == True:
try:
# 截图保存到文件
mytapi.screentshot(1, 90, "screenshot.png")
# 截图获取字节数据
byt_arr = mytapi.takeCaptrueCompress(0, 100) # 0=PNG, 100=质量
if byt_arr != False and len(byt_arr) > 0:
print(f"截图大小: {len(byt_arr)} 字节")
# 指定区域截图保存
mytapi.screentshotEx(100, 100, 500, 800, 1, 90, "region.jpg")
finally:
pass
if __name__ == "__main__":
main()
触摸操作示例
from common.mytRpc import MytRpc
import time
def main():
mytapi = MytRpc()
if mytapi.init("192.168.1.100", 30202, 10) == True:
try:
# 单击
mytapi.touchClick(0, 500, 500)
time.sleep(1)
# 长按
mytapi.longClick(0, 500, 500, 1.0) # 1.0秒
time.sleep(1)
# 滑动
mytapi.swipe(0, 100, 500, 500, 500, 1000) # 持续1秒
finally:
pass
if __name__ == "__main__":
main()
按键和文本输入示例
from common.mytRpc import MytRpc
def main():
mytapi = MytRpc()
if mytapi.init("192.168.1.100", 30202, 10) == True:
try:
# 发送文本
mytapi.sendText("Hello MYT RPA!")
# 清除文字
mytapi.ClearText(5)
# 快捷按键
mytapi.pressBack() # 返回键
mytapi.pressHome() # Home键
mytapi.pressEnter() # 回车键
mytapi.pressRecent() # 最近任务键
# 自定义按键码
mytapi.keyPress(26) # 电源键
finally:
pass
if __name__ == "__main__":
main()
App操作示例
from common.mytRpc import MytRpc
def main():
mytapi = MytRpc()
if mytapi.init("192.168.1.100", 30202, 10) == True:
try:
# 打开应用
if mytapi.openApp("com.blue.filemanager"):
print("应用打开成功")
# 停止应用
if mytapi.stopApp("com.blue.filemanager"):
print("应用关闭成功")
finally:
pass
if __name__ == "__main__":
main()
节点操作示例
from common.mytRpc import MytRpc
def main():
mytapi = MytRpc()
if mytapi.init("192.168.1.100", 30202, 10) == True:
try:
# 导出节点树
node_xml = mytapi.dumpNodeXml(1)
if node_xml != False:
with open("nodes.xml", "w", encoding='utf-8') as f:
f.write(node_xml)
# 使用选择器查找节点
selector = mytapi.create_selector()
with selector:
selector.addQuery_TextContainWith('登录')
selector.addQuery_Clickable(1)
node = selector.execQueryOne(2000) # 超时2秒
if node is not None:
print(f"节点信息: {node.getNodeJson()}")
node.Click_events()
else:
print("未找到匹配节点")
finally:
pass
if __name__ == "__main__":
main()
便捷方法示例
from common.mytRpc import MytRpc
def main():
mytapi = MytRpc()
if mytapi.init("192.168.1.100", 30202, 10) == True:
try:
# 一行代码查找并点击
mytapi.clickText("确定")
mytapi.clickId("com.example:id/btn_login")
mytapi.clickClass("android.widget.Button")
mytapi.clickDesc("提交按钮")
# 便捷节点查找(返回JSON字符串)
nodes_json = mytapi.getNodeByText("登录")
if nodes_json is not None:
print(f"找到节点: {nodes_json}")
finally:
pass
if __name__ == "__main__":
main()
执行Shell命令示例
from common.mytRpc import MytRpc
def main():
mytapi = MytRpc()
if mytapi.init("192.168.1.100", 30202, 10) == True:
try:
output, success = mytapi.exec_cmd("ls /data")
if success:
print(f"命令输出: {output}")
finally:
pass
if __name__ == "__main__":
main()
按键码参考
# 常用按键码列表
KEYCODE_HOME = 3 # Home键
KEYCODE_BACK = 4 # 返回键
KEYCODE_CALL = 5 # 拨号键
KEYCODE_ENDCALL = 6 # 挂机键
KEYCODE_VOLUME_UP = 24 # 音量增加键
KEYCODE_VOLUME_DOWN = 25 # 音量减小键
KEYCODE_POWER = 26 # 电源键
KEYCODE_CAMERA = 27 # 拍照键
KEYCODE_ENTER = 66 # 回车键
KEYCODE_DEL = 67 # 退格键
KEYCODE_MENU = 82 # 菜单键
KEYCODE_SEARCH = 84 # 搜索键
KEYCODE_TAB = 61 # Tab键
MYT RPA SDK Go 语言 API 文档
Go 语言版本的 SDK 提供了 RPA 自动化、Android 云手机控制等功能。
模块路径:cnb.cool/openmyt/myt-sdk-golang
Go 版本:1.18+
安装说明
-
将
rpa_sdk文件夹复制到你的 Go 项目 -
执行依赖同步
go mod tidy
- 导入包即可使用
import "rpa_sdk/rpa_sdk"
- 使用实例
c := rpa_sdk.NewController()
err := c.Connect("192.168.30.2", 30002)
目录
一、初始化与连接
1.1. NewController
创建RPA控制器
func NewController() *Controller
1.2. Connect
连接RPA设备
func (c *Controller) Connect(ip string, port uint16) error
1.3. Close
关闭连接
func (c *Controller) Close()
二、基础设备方法
2.1. CheckAlive
检查设备是否存活
func (c *Controller) CheckAlive() error
2.2. ExecCmd
执行 Shell 命令
func (c *Controller) ExecCmd(wait int, cmd string) (string, error)
2.3. DumpNodeXml
获取当前界面 XML
func (c *Controller) DumpNodeXml(all bool) (string, error)
2.4. GetDisplayRotate
获取屏幕旋转角度
func (c *Controller) GetDisplayRotate() (int, error)
三、截图方法
3.1. TakeCapture
全屏截图(原始RGBA数据)
func (c *Controller) TakeCapture() (ImageData, error)
ImageData 结构体:
| 字段 | 类型 | 说明 |
|---|---|---|
| Width | int | 图像宽度 |
| Height | int | 图像高度 |
| Stride | int | 图像步长 |
| Pixels | []byte | RGBA像素数据 |
3.2. TakeCaptureCompress
压缩截图(JPEG/PNG)
func (c *Controller) TakeCaptureCompress(typ int, quality int) ([]byte, error)
| 参数 | 类型 | 说明 |
|---|---|---|
| typ | int | 0表示PNG,1表示JPG |
| quality | int | 压缩质量,取值0-100 |
四、触摸操作方法
4.1. Touch
基础触摸事件
func (c *Controller) Touch(touchId, event, x, y int) error
| 参数 | 类型 | 说明 |
|---|---|---|
| touchId | int | 手指编号 |
| event | int | 事件类型 |
| x | int | X坐标 |
| y | int | Y坐标 |
4.2. Swipe
滑动事件
func (c *Controller) Swipe(touchId, x0, y0, x1, y1, ms int, async bool) error
五、按键和文本输入
5.1. SendText
输入文本
func (c *Controller) SendText(text string) error
5.2. KeyEvent
按键事件
func (c *Controller) KeyEvent(keyCode int) error
六、App操作方法
6.1. RunOrStopApp
运行或停止应用
func (c *Controller) RunOrStopApp(flag int, packageName string) error
| 参数 | 类型 | 说明 |
|---|---|---|
| flag | int | 1=运行应用,0=停止应用 |
| packageName | str | 应用包名 |
七、选择器与节点操作
Go 版本的选择器与节点系统采用流畅API(Fluent API)设计,支持链式调用。
7.1 创建选择器
sel := c.NewSelector()
7.2 选择器筛选方法
字符串匹配(每种属性支持5种匹配模式:Equal、StartWith、EndWith、ContainWith、MatchWith):
| 属性 | 方法前缀 | 示例 |
|---|---|---|
| Text | Text* | sel.TextEqual("登录") |
| Id | Id* | sel.IdContainWith("btn") |
| Desc | Desc* | sel.DescStartWith("按钮") |
| Class | Class* | sel.ClassEqual("Button") |
| Package | Package* | sel.PackageEqual("com.app") |
布尔属性匹配:
| 方法 | 说明 |
|---|---|
Clickable(v) | 可点击 |
Checkable(v) | 可选中 |
Enabled(v) | 可用 |
Focusable(v) | 可获取焦点 |
Focused(v) | 已获取焦点 |
Checked(v) | 已选中 |
Scrollable(v) | 可滚动 |
LongClickable(v) | 可长按 |
Password(v) | 密码 |
Selected(v) | 已选择 |
Visible(v) | 可见 |
整数匹配:
| 方法 | 说明 |
|---|---|
IndexEqual(v) | 索引匹配 |
DepthEqual(v) | 深度匹配 |
DrawingOrderEqual(v) | 绘制顺序匹配 |
边界匹配:
| 方法 | 说明 |
|---|---|
BoundsEqual(l,t,r,b) | 边界完全匹配 |
BoundsInside(l,t,r,b) | 边界在指定范围内 |