OpenClawSkills
GitHub
Platforms β€’ TutorialHeader.readTime

Android App

Android node app: connection guide + Canvas/Chat/Camera.

Tutorial.step

Support Overview

- Role: Companion node app (Android does not host Gateway).

- Gateway required: Yes (run on macOS, Linux, or Windows (WSL2)).

- Install reference: ''Getting Started'' + ''Pairing''.

- Gateway reference: ''Runbook'' + ''Configuration''.

- Protocol: ''Gateway protocol'' (node ↔ control plane).

Tutorial.step

System Control

System-level control (launchd/systemd) happens on the Gateway host. See ''Gateway''.

Tutorial.step

Connection Guide (Runbook)

Android node app ⇄ (mDNS/NSD + WebSocket) ⇄ Gateway

Android connects directly to Gateway WebSocket (default ws://<host>:18789) and uses the pairing mechanism managed by Gateway.

#

Tutorial.step

Prerequisites

- You can run Gateway on your "primary" machine.

- Android device/emulator can access the gateway WebSocket:

- Same LAN, discovered via mDNS/NSD, OR

- Same Tailscale tailnet, via Wide-Area Bonjour / unicast DNS-SD (see below), OR

- Manual gateway host/port entry (fallback)

- You can run CLI (openclaw) on the gateway machine (or via SSH).

#

Tutorial.step

1) Start Gateway

Bash
openclaw gateway --port 18789 --verbose

Confirm logs show something like:

- listening on ws://0.0.0.0:18789

For tailnet-only deployments (e.g., Vienna ⇄ London, recommended), bind gateway to tailnet IP:

- Set gateway.bind: "tailnet" in ~/.openclaw/openclaw.json on gateway host.

- Restart Gateway / macOS menu bar app.

#

Tutorial.step

2) Verify Discovery (Optional)

On gateway machine:

Bash
dns-sd -B _openclaw-gw._tcp local.

For more debugging info, see ''Bonjour''.

##

Tutorial.step

Tailnet (Vienna ⇄ London) Discovery via Unicast DNS-SD

Android's NSD/mDNS discovery cannot cross networks. If Android node and gateway are not on the same network but connected via Tailscale, use Wide-Area Bonjour / unicast DNS-SD:

1. Set up a DNS-SD zone on gateway host (e.g., openclaw.internal.) and publish _openclaw-gw._tcp records.

2. Configure split DNS in Tailscale for that domain, pointing to your DNS server.

See ''Bonjour'' for details and CoreDNS examples.

#

Tutorial.step

3) Connect from Android

In the Android app:

- App maintains connection to gateway via foreground service (persistent notification).

- Open Settings.

- Select your gateway in Discovered Gateways, then tap Connect.

- If mDNS is blocked, use Advanced β†’ Manual Gateway (host + port) and tap Connect (Manual).

After successful initial pairing, Android will auto-retry on startup:

- If manual endpoint is enabled, it prioritizes manual endpoint; otherwise

- Tries to reconnect to the last discovered gateway (best effort).

#

Tutorial.step

4) Approve Pairing (CLI)

On gateway machine:

Bash
openclaw nodes pending
openclaw nodes approve <requestId>

Pairing details: ''/gateway/pairing''.

#

Tutorial.step

5) Verify Node is Connected

- Node status:

- Via Gateway:

PlatformsAndroidPage step 10: P3

Tutorial.step

6) Chat & History Sync

Android node's Chat page uses gateway's primary session key (main), so chat history and replies are shared with clients like WebChat:

- History: chat.history

- Send: chat.send

- Push updates (best effort): chat.subscribe β†’ event:"chat"

#

Tutorial.step

7) Canvas + Camera

##

Tutorial.step

Gateway Canvas Host (Recommended for Displaying Web Content)

If you want the node to display real HTML/CSS/JS (edited by Agent on disk), connect the node to a Gateway canvas host.

Note: Node uses a separate canvas host on port canvasHost.port (default 18793).

1. Create ~/.openclaw/workspace/canvas/index.html on gateway host.

2. Have node navigate to it (LAN):

Tailnet (optional): If both devices are on Tailscale, use MagicDNS or tailnet IP instead of .local, e.g., http://<gateway-magicdns>:18793/__openclaw__/canvas/.

This service injects a live-reload client into the HTML and auto-refreshes on file changes. A2UI host is at http://<gateway-host>:18793/__openclaw__/a2ui/.

Canvas commands (foreground only):

- canvas.eval, canvas.snapshot, canvas.navigate (use '{"url":""}' or '{"url":"/"}' to return to default scaffold). canvas.snapshot returns '{ format, base64 }' (default format="jpeg").

- A2UI: canvas.a2ui.push, canvas.a2ui.reset (old alias canvas.a2ui.pushJSONL still available)

Camera commands (foreground only; permission-controlled):

- camera.snap (jpg)

- camera.clip (mp4)

See ''Camera node'' for parameters and CLI helpers.