# 用 Codex 控制 Android 手机 OpenGUI 让 Codex / Claude Code 可以把自然语言任务交给一台真实 Android 手机执行。Codex 不直接点坐标,也不直接处理 Android socket 协议;它通过 OpenGUI 后端创建任务,后端再把执行请求交给在线的 Android client。 ## 整体链路 Codex / Claude Code 是入口,OpenGUI backend 负责保存任务和执行状态,Android client 负责截图、动作执行和设备侧状态回传。任务进入后端之后,会通过 standby 连接发送到手机在线设备,再进入 execution socket 的执行循环。 ```mermaid flowchart LR U["Developer"] --> A["Codex / Claude Code"] A --> S["open-gui-remote-control Skill"] S --> CLI["server CLI
pnpm opengui -- ... --json"] CLI --> BE["OpenGUI backend
Task / Execution"] BE --> ST["Standby dispatch"] ST --> AC["Android client"] AC --> EX["Execution socket"] EX --> VLM["Screenshot + VLM"] VLM --> ACT["Accessibility action"] ACT --> AC ``` `task` 是任务定义,描述要做什么。`execution` 是一次具体执行,一个 task 可以运行多次,每次运行都会生成新的 `executionId`。`do` 命令创建 task 并立刻创建 execution;`run ` 复用已有 task 并创建新的 execution;`status ` 查询某次执行的状态。 ## Skill 边界 `open-gui-bootstrap` 用来启动 OpenGUI。它负责仓库检查、依赖安装、后端启动、Android client 构建安装、`adb reverse` 和模型配置。 `open-gui-remote-control` 用来控制已经接入 OpenGUI 的手机。它负责设备发现、任务创建、任务运行、状态查询、暂停、恢复和取消。 从空环境开始时,先用 bootstrap。后端已启动、Android client 已安装并在线时,直接用 remote control。 ## 运行环境 本地手机控制应运行在连接 Android 手机的开发机上。这个环境需要能运行 Node.js 22、pnpm、Docker、Java 和 adb,并且已经拿到 OpenGUI 仓库: ```text https://github.com/Core-Mate/open-gui ``` 可运行的 OpenGUI 仓库包含: ```text server/package.json client/start.sh ``` Android 侧需要完成 USB debugging 授权,并为 OpenGUI App 开启 Accessibility Service 和悬浮窗权限。使用 USB 连接本机后端时,需要建立端口反向代理: ```bash adb reverse tcp:7777 tcp:7777 ``` 后端默认地址是: ```text http://localhost:7777 ``` 后端需要先可访问,Android client 才能稳定建立 standby 连接。Android client 已安装时,保持 App 打开即可,不需要重新构建。 远端运行只适合设备桥接已经配置好的场景。普通 USB 手机控制不适合把 backend 放到远端,因为 USB debugging、APK 安装和 `adb reverse` 都发生在连接手机的本机环境里。 ## 使用方式 OpenGUI 已经启动时,把下面这段交给 Codex / Claude Code: ```text Read ./skills/open-gui-remote-control/SKILL.md and use OpenGUI to control my Android phone. Task: 观察当前手机屏幕,简要描述你看到了什么,然后结束。 Only ask me for phone-side permissions or missing secrets. ``` OpenGUI 还没有启动时,先让 agent 执行 bootstrap,再进入 remote control: ```text Read ./skills/open-gui-bootstrap/SKILL.md first to start OpenGUI. Then read ./skills/open-gui-remote-control/SKILL.md and run this phone task: 观察当前手机屏幕,简要描述你看到了什么,然后结束。 ``` Skill 会优先使用仓库里的 CLI。对应的本地命令是: ```bash cd server pnpm opengui -- devices --json pnpm opengui -- do "观察当前手机屏幕,简要描述你看到了什么,然后结束" --json pnpm opengui -- status --json ``` 多台设备在线时,先读取设备列表,再指定目标设备: ```bash pnpm opengui -- devices --json pnpm opengui -- do "打开设置,检查当前网络状态" --device --json ``` 后端不在默认地址时,显式传入 base URL: ```bash pnpm opengui -- devices --base-url --json ``` `--json` 用于给 Codex / Claude Code 返回结构化结果,方便读取 `deviceId`、`taskId`、`executionId` 和 execution 状态。 ## 执行模型 OpenGUI 不走坐标脚本。`adb shell input tap` 只能点固定坐标,不知道当前屏幕内容,也不知道任务执行到了哪一步。权限弹窗、登录页、网络加载、推荐浮层和系统中断都会让坐标脚本失效。 OpenGUI 的执行状态保存在后端。Android client 上传截图和设备状态,VLM 理解屏幕并生成下一步动作,Android AccessibilityService 负责执行动作。Codex / Claude Code 只需要通过 CLI 或 REST API 观察 execution 状态,并在需要时暂停、恢复或取消任务。 ## 故障处理 仓库路径不对时,检查当前目录或子目录是否存在 `server/package.json` 和 `client/start.sh`。如果不存在,使用 `https://github.com/Core-Mate/open-gui` 获取可运行仓库。 `devices` 返回空时,检查 Android client 是否连上 backend:backend 是否运行,手机是否打开 OpenGUI App,USB debugging 是否授权,`adb reverse tcp:7777 tcp:7777` 是否执行,Accessibility Service 和悬浮窗权限是否开启。 `fetch failed` 表示 CLI 没有连上 backend。先访问 `http://localhost:7777/docs`;后端运行在其他地址时,用 `--base-url `。 远端 backend 默认不能控制本地 USB 手机。本地手机通过 USB 和 `adb reverse` 连接的是本机环境。只有手机能访问远端 backend,并且设备连接链路已经配置好时,远端运行才成立。