平台概览
Android 应用
支持快照
- 角色:配套节点应用(Android 不托管 Gateway 网关)。
- 需要 Gateway 网关:是(通过 WSL2 在 macOS、Linux 或 Windows 上运行)。
- 安装:入门指南 + 配对。
- Gateway 网关:运行手册 + 配置。
- 协议:Gateway 网关协议(节点 + 控制平面)。
系统控制
系统控制(launchd/systemd)位于 Gateway 网关主机上。请参阅 Gateway 网关。
连接运行手册
Android 节点应用 ⇄(mDNS/NSD + WebSocket)⇄ Gateway 网关
Android 直接连接到 Gateway 网关 WebSocket,并使用设备配对(role: node)。
对于 Tailscale 或公网主机,Android 需要安全端点:
- 首选:Tailscale Serve / Funnel,使用
https://<magicdns>/wss://<magicdns> - 同样支持:任何其他带有真实 TLS 端点的
wss://Gateway 网关 URL - 明文
ws://仍支持私有 LAN 地址 /.local主机,以及localhost、127.0.0.1和 Android 模拟器桥接地址(10.0.2.2)
前提条件
- 你可以在“主”机器上运行 Gateway 网关。
- Android 设备/模拟器可以访问 Gateway 网关 WebSocket:
- 同一 LAN,使用 mDNS/NSD,或
- 同一 Tailscale tailnet,使用 Wide-Area Bonjour / 单播 DNS-SD(见下文),或
- 手动 Gateway 网关主机/端口(回退)
- Tailnet/公网移动端配对不使用原始 tailnet IP
ws://端点。请改用 Tailscale Serve 或其他wss://URL。 - 你可以在 Gateway 网关机器上(或通过 SSH)运行 CLI(
openclaw)。
1) 启动 Gateway 网关
openclaw gateway --port 18789 --verbose
确认日志中能看到类似内容:
listening on ws://0.0.0.0:18789
对于通过 Tailscale 远程访问 Android,优先使用 Serve/Funnel,而不是原始 tailnet 绑定:
openclaw gateway --tailscale serve
这会为 Android 提供安全的 wss:// / https:// 端点。普通的 gateway.bind: "tailnet" 设置不足以完成首次远程 Android 配对,除非你还单独终止 TLS。
2) 验证设备发现(可选)
在 Gateway 网关机器上:
dns-sd -B _openclaw-gw._tcp local.
更多调试说明:Bonjour。
如果你还配置了广域发现域名,请对比:
openclaw gateway discover --json
它会一次性显示 local. 加上配置的广域域名,并使用解析后的服务端点,而不是只依赖 TXT 提示。
通过单播 DNS-SD 进行 tailnet(维也纳 ⇄ 伦敦)发现
Android NSD/mDNS 发现无法跨网络。如果你的 Android 节点和 Gateway 网关位于不同网络,但通过 Tailscale 连接,请改用 Wide-Area Bonjour / 单播 DNS-SD。
仅有设备发现不足以进行 tailnet/公网 Android 配对。发现到的路由仍需要安全端点(wss:// 或 Tailscale Serve):
- 在 Gateway 网关主机上设置 DNS-SD 区域(例如
openclaw.internal.),并发布_openclaw-gw._tcp记录。 - 为你选择的域配置 Tailscale split DNS,指向该 DNS 服务器。
详细信息和 CoreDNS 示例配置:Bonjour。
3) 从 Android 连接
在 Android 应用中:
- 应用通过前台服务(持久通知)保持 Gateway 网关连接存活。
- 打开 Connect 选项卡。
- 使用 Setup Code 或 Manual 模式。
- 如果设备发现被阻止,请在 Advanced controls 中使用手动主机/端口。对于私有 LAN 主机,
ws://仍可使用。对于 Tailscale/公网主机,请开启 TLS 并使用wss:/// Tailscale Serve 端点。
首次成功配对后,Android 会在启动时自动重新连接:
- 手动端点(如果已启用),否则
- 上次发现的 Gateway 网关(尽力而为)。
在线状态存活信标
在经过身份验证的节点会话连接后,以及应用进入后台但前台服务仍保持连接时,Android 会调用 node.event,并带上 event: "node.presence.alive"。Gateway 网关只有在已知经过身份验证的节点设备身份之后,才会把它记录为已配对节点/设备元数据上的 lastSeenAtMs/lastSeenReason。
只有当 Gateway 网关响应包含 handled: true 时,应用才会把该信标计为成功记录。旧版 Gateway 网关可能会用 { "ok": true } 确认 node.event;该响应兼容,但不会计为持久的最后可见时间更新。
4) 批准配对(CLI)
在 Gateway 网关机器上:
openclaw devices list
openclaw devices approve <requestId>
openclaw devices reject <requestId>
配对详情:配对。
可选:如果 Android 节点始终从严格受控的子网连接,你可以通过显式 CIDR 或精确 IP 选择启用首次节点自动批准:
{
gateway: {
nodes: {
pairing: {
autoApproveCidrs: ["192.168.1.0/24"],
},
},
},
}
默认禁用。它仅适用于没有请求作用域的新 role: node 配对。操作员/浏览器配对,以及任何角色、作用域、元数据或公钥变更,仍需要手动批准。
5) 验证节点已连接
-
通过节点 Status:
openclaw nodes status -
通过 Gateway 网关:
openclaw gateway call node.list --params "{}"
6) 聊天 + 历史记录
Android Chat 选项卡支持会话选择(默认 main,以及其他现有会话):
- 历史记录:
chat.history(显示已规范化;内联指令标签会从可见文本中剥离,纯文本工具调用 XML 载荷(包括<tool_call>...</tool_call>、<function_call>...</function_call>、<tool_calls>...</tool_calls>、<function_calls>...</function_calls>和被截断的工具调用块)以及泄漏的 ASCII/全角模型控制令牌会被剥离,精确为NO_REPLY/no_reply等纯静默令牌的 assistant 行会被省略,过大的行可被替换为占位符) - 发送:
chat.send - 推送更新(尽力而为):
chat.subscribe→event:"chat"
7) Canvas + 摄像头
Gateway 网关 Canvas 主机(推荐用于 Web 内容)
如果你希望节点显示智能体可以在磁盘上编辑的真实 HTML/CSS/JS,请将节点指向 Gateway 网关 canvas 主机。
-
在 Gateway 网关主机上创建
~/.openclaw/workspace/canvas/index.html。 -
将节点导航到该位置(LAN):
openclaw nodes invoke --node "<Android Node>" --command canvas.navigate --params '{"url":"http://<gateway-hostname>.local:18789/__openclaw__/canvas/"}'
Tailnet(可选):如果两台设备都在 Tailscale 上,请使用 MagicDNS 名称或 tailnet IP,而不是 .local,例如 http://<gateway-magicdns>:18789/__openclaw__/canvas/。
该服务器会向 HTML 注入实时重载客户端,并在文件变更时重新加载。
A2UI 主机位于 http://<gateway-host>:18789/__openclaw__/a2ui/。
Canvas 命令(仅前台):
canvas.eval、canvas.snapshot、canvas.navigate(使用{"url":""}或{"url":"/"}返回默认脚手架)。canvas.snapshot返回{ format, base64 }(默认format="jpeg")。- A2UI:
canvas.a2ui.push、canvas.a2ui.reset(canvas.a2ui.pushJSONL旧版别名)
摄像头命令(仅前台;受权限控制):
camera.snap(jpg)camera.clip(mp4)
参数和 CLI 辅助工具请参阅摄像头节点。
8) 语音 + 扩展的 Android 命令表面
- 语音选项卡:Android 有两种显式采集模式。Mic 是手动的语音选项卡会话,会把每次停顿作为聊天轮次发送,并在应用离开前台或用户离开语音选项卡时停止。Talk 是连续的 Talk 模式,会持续监听,直到被关闭或节点断开连接。
- Talk 模式会在采集开始前将现有前台服务从
dataSync提升为dataSync|microphone,然后在 Talk 模式停止时降级。Android 14+ 要求声明FOREGROUND_SERVICE_MICROPHONE、授予RECORD_AUDIO运行时权限,并在运行时使用麦克风服务类型。 - 语音回复通过配置的 Gateway 网关 Talk 提供商使用
talk.speak。仅在talk.speak不可用时才使用本地系统 TTS。 - Android UX/运行时中仍禁用语音唤醒。
- 其他 Android 命令族(可用性取决于设备 + 权限):
device.status、device.info、device.permissions、device.healthnotifications.list、notifications.actions(见下方通知转发)photos.latestcontacts.search、contacts.addcalendar.events、calendar.addcallLog.searchsms.searchmotion.activity、motion.pedometer
Assistant 入口点
Android 支持从系统 assistant 触发器(Google Assistant)启动 OpenClaw。配置后,长按主屏幕按钮或说“Hey Google, ask OpenClaw...”会打开应用,并将提示词交给聊天输入框。
这使用 Android App Actions 元数据,该元数据在应用清单中声明。Gateway 网关侧无需额外配置;assistant intent 完全由 Android 应用处理,并作为普通聊天消息转发。
通知转发
Android 可以将设备通知作为事件转发到 Gateway 网关。多个控制项可用于限定转发哪些通知以及何时转发。
| 键 | 类型 | 描述 |
|---|---|---|
notifications.allowPackages |
string[] | 仅转发来自这些包名的通知。如果已设置,所有其他包都会被忽略。 |
notifications.denyPackages |
string[] | 永不转发来自这些包名的通知。在 allowPackages 之后应用。 |
notifications.quietHours.start |
string (HH:mm) | 免打扰时段窗口的开始时间(本地设备时间)。此窗口期间会抑制通知。 |
notifications.quietHours.end |
string (HH:mm) | 免打扰时段窗口的结束时间。 |
notifications.rateLimit |
number | 每个包每分钟最多转发的通知数。超出的通知会被丢弃。 |
通知选择器还会对转发的通知事件使用更安全的行为,防止意外转发敏感系统通知。
配置示例:
{
notifications: {
allowPackages: ["com.slack", "com.whatsapp"],
denyPackages: ["com.android.systemui"],
quietHours: {
start: "22:00",
end: "07:00",
},
rateLimit: 5,
},
}