Platforms overview
App Android
Snapshot del supporto
- Ruolo: app nodo companion (Android non ospita il Gateway).
- Gateway richiesto: sì (eseguilo su macOS, Linux o Windows tramite WSL2).
- Installazione: Google Play per l'app, Guida introduttiva per il Gateway, poi Abbinamento.
- Gateway: Runbook + Configurazione.
- Protocolli: Protocollo Gateway (nodi + piano di controllo).
Controllo di sistema
Il controllo di sistema (launchd/systemd) risiede sull'host del Gateway. Vedi Gateway.
Runbook di connessione
App nodo Android ⇄ (mDNS/NSD + WebSocket) ⇄ Gateway
Android si connette direttamente al WebSocket del Gateway e usa l'abbinamento del dispositivo (role: node).
Per Tailscale o host pubblici, Android richiede un endpoint sicuro:
- Preferito: Tailscale Serve / Funnel con
https://<magicdns>/wss://<magicdns> - Supportato anche: qualsiasi altro URL Gateway
wss://con un endpoint TLS reale ws://in chiaro resta supportato su indirizzi LAN privati / host.local, piùlocalhost,127.0.0.1e il bridge dell'emulatore Android (10.0.2.2)
Prerequisiti
- Puoi eseguire il Gateway sulla macchina "master".
- Il dispositivo/emulatore Android può raggiungere il WebSocket del Gateway:
- Stessa LAN con mDNS/NSD, oppure
- Stessa tailnet Tailscale usando Wide-Area Bonjour / DNS-SD unicast (vedi sotto), oppure
- Host/porta del gateway manuali (fallback)
- L'abbinamento mobile tailnet/pubblico non usa endpoint IP tailnet grezzi
ws://. Usa invece Tailscale Serve o un altro URLwss://. - Puoi eseguire la CLI (
openclaw) sulla macchina gateway (o tramite SSH).
1) Avvia il Gateway
openclaw gateway --port 18789 --verboseConferma nei log di vedere qualcosa come:
listening on ws://0.0.0.0:18789
Per l'accesso Android remoto su Tailscale, preferisci Serve/Funnel invece di un bind tailnet grezzo:
openclaw gateway --tailscale serveQuesto fornisce ad Android un endpoint sicuro wss:// / https://. Una semplice configurazione gateway.bind: "tailnet" non basta per il primo abbinamento Android remoto, a meno che tu non termini anche TLS separatamente.
2) Verifica il rilevamento (opzionale)
Dalla macchina gateway:
dns-sd -B _openclaw-gw._tcp local.Altre note di debug: Bonjour.
Se hai configurato anche un dominio di rilevamento wide-area, confronta con:
openclaw gateway discover --jsonMostra local. più il dominio wide-area configurato in un unico passaggio e usa l'endpoint
di servizio risolto invece di suggerimenti solo TXT.
Rilevamento tailnet (Vienna ⇄ Londra) tramite DNS-SD unicast
Il rilevamento NSD/mDNS di Android non attraversa le reti. Se il nodo Android e il gateway sono su reti diverse ma connessi tramite Tailscale, usa invece Wide-Area Bonjour / DNS-SD unicast.
Il solo rilevamento non è sufficiente per l'abbinamento Android tailnet/pubblico. La route rilevata richiede comunque un endpoint sicuro (wss:// o Tailscale Serve):
- Configura una zona DNS-SD (esempio
openclaw.internal.) sull'host gateway e pubblica record_openclaw-gw._tcp. - Configura il DNS split di Tailscale per il dominio scelto, puntandolo a quel server DNS.
Dettagli ed esempio di configurazione CoreDNS: Bonjour.
3) Connettiti da Android
Nell'app Android:
- L'app mantiene attiva la connessione al gateway tramite un servizio in primo piano (notifica persistente).
- Apri la scheda Connetti.
- Usa la modalità Codice di configurazione o Manuale.
- Se il rilevamento è bloccato, usa host/porta manuali in Controlli avanzati. Per host LAN privati,
ws://funziona ancora. Per host Tailscale/pubblici, attiva TLS e usa un endpointwss:/// Tailscale Serve.
Dopo il primo abbinamento riuscito, Android si riconnette automaticamente all'avvio:
- Endpoint manuale (se abilitato), altrimenti
- L'ultimo gateway rilevato (best-effort).
Beacon di presenza attiva
Dopo che la sessione del nodo autenticato si connette, e quando l'app passa in background mentre il
servizio in primo piano è ancora connesso, Android chiama node.event con
event: "node.presence.alive". Il gateway lo registra come lastSeenAtMs/lastSeenReason sui
metadati del nodo/dispositivo abbinato solo dopo che l'identità del dispositivo nodo autenticato è nota.
L'app considera il beacon registrato correttamente solo quando la risposta del gateway include
handled: true. Gateway più vecchi possono confermare node.event con { "ok": true }; quella risposta è
compatibile ma non conta come aggiornamento persistente dell'ultimo visto.
4) Approva l'abbinamento (CLI)
Sulla macchina gateway:
openclaw devices listopenclaw devices approve <requestId>openclaw devices reject <requestId>Dettagli sull'abbinamento: Abbinamento.
Opzionale: se il nodo Android si connette sempre da una subnet strettamente controllata, puoi abilitare la prima approvazione automatica del nodo con CIDR espliciti o IP esatti:
{ gateway: { nodes: { pairing: { autoApproveCidrs: ["192.168.1.0/24"], }, }, },}È disabilitato per impostazione predefinita. Si applica solo a nuovi abbinamenti role: node senza
scope richiesti. L'abbinamento operatore/browser e qualsiasi modifica di ruolo, scope, metadati o
chiave pubblica richiedono comunque l'approvazione manuale.
5) Verifica che il nodo sia connesso
-
Tramite stato dei nodi:
bash openclaw nodes status -
Tramite Gateway:
bash openclaw gateway call node.list --params "{}"
6) Chat + cronologia
La scheda Chat di Android supporta la selezione della sessione (predefinita main, più altre sessioni esistenti):
- Cronologia:
chat.history(normalizzata per la visualizzazione; i tag direttiva inline vengono rimossi dal testo visibile, i payload XML di chiamate tool in testo semplice (inclusi<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>e blocchi di chiamate tool troncati) e i token di controllo del modello ASCII/full-width trapelati vengono rimossi, le righe assistant di soli token silenziosi come esattamenteNO_REPLY/no_replyvengono omesse, e le righe sovradimensionate possono essere sostituite con placeholder) - Invio:
chat.send - Aggiornamenti push (best-effort):
chat.subscribe→event:"chat"
7) Canvas + fotocamera
Host Canvas del Gateway (consigliato per contenuti web)
Se vuoi che il nodo mostri HTML/CSS/JS reale che l'agente può modificare su disco, punta il nodo all'host canvas del Gateway.
-
Crea
~/.openclaw/workspace/canvas/index.htmlsull'host gateway. -
Naviga il nodo lì (LAN):
openclaw nodes invoke --node "<Android Node>" --command canvas.navigate --params '{"url":"http://<gateway-hostname>.local:18789/__openclaw__/canvas/"}'Tailnet (opzionale): se entrambi i dispositivi sono su Tailscale, usa un nome MagicDNS o un IP tailnet invece di .local, ad esempio http://<gateway-magicdns>:18789/__openclaw__/canvas/.
Questo server inietta un client live-reload nell'HTML e ricarica alle modifiche dei file.
Il Gateway serve anche /__openclaw__/a2ui/, ma l'app Android tratta le pagine A2UI remote come solo rendering. I comandi A2UI con azioni usano la pagina A2UI inclusa e di proprietà dell'app prima di applicare i messaggi.
Comandi canvas (solo in primo piano):
canvas.eval,canvas.snapshot,canvas.navigate(usa{"url":""}o{"url":"/"}per tornare allo scaffold predefinito).canvas.snapshotrestituisce{ format, base64 }(format="jpeg"predefinito).- A2UI:
canvas.a2ui.push,canvas.a2ui.reset(canvas.a2ui.pushJSONLalias legacy). Questi comandi usano la pagina A2UI inclusa e di proprietà dell'app per il rendering con azioni.
Comandi fotocamera (solo in primo piano; protetti da permesso):
camera.snap(jpg)camera.clip(mp4)
Vedi Nodo fotocamera per parametri e helper CLI.
8) Voce + superficie comandi Android estesa
- Scheda Voce: Android ha due modalità di acquisizione esplicite. Mic è una sessione manuale della scheda Voce che invia ogni pausa come turno di chat e si interrompe quando l'app lascia il primo piano o l'utente lascia la scheda Voce. Talk è la modalità Talk continua e continua ad ascoltare finché non viene disattivata o il nodo si disconnette.
- La modalità Talk promuove il servizio in primo piano esistente da
connectedDeviceaconnectedDevice|microphoneprima dell'inizio dell'acquisizione, poi lo retrocede quando la modalità Talk si arresta. Il servizio del nodo dichiaraFOREGROUND_SERVICE_CONNECTED_DEVICEconCHANGE_NETWORK_STATE; Android 14+ richiede anche la dichiarazioneFOREGROUND_SERVICE_MICROPHONE, la concessione runtimeRECORD_AUDIOe il tipo di servizio microfono a runtime. - Per impostazione predefinita, Talk di Android usa il riconoscimento vocale nativo, la chat del Gateway e
talk.speaktramite il provider Talk del gateway configurato. Il TTS di sistema locale viene usato solo quandotalk.speaknon è disponibile. - Talk di Android usa il relay realtime del Gateway solo quando
talk.realtime.modeèrealtimeetalk.realtime.transportègateway-relay. - Il wake vocale resta disabilitato nella UX/runtime Android.
- Famiglie di comandi Android aggiuntive (la disponibilità dipende da dispositivo, permessi e impostazioni utente):
device.status,device.info,device.permissions,device.healthdevice.appssolo quando Impostazioni > Capacità telefono > App installate è abilitato; per impostazione predefinita elenca le app visibili nel launcher.notifications.list,notifications.actions(vedi Inoltro notifiche sotto)photos.latestcontacts.search,contacts.addcalendar.events,calendar.addcallLog.searchsms.searchmotion.activity,motion.pedometer
Entry point dell'assistant
Android supporta l'avvio di OpenClaw dal trigger dell'assistant di sistema (Google Assistant). Quando configurato, tenere premuto il pulsante Home o dire "Hey Google, ask OpenClaw..." apre l'app e passa il prompt nel compositore della chat.
Questo usa i metadati App Actions di Android dichiarati nel manifest dell'app. Non è necessaria alcuna configurazione extra lato gateway: l'intent dell'assistant è gestito interamente dall'app Android e inoltrato come normale messaggio di chat.
Inoltro notifiche
Android può inoltrare le notifiche del dispositivo al gateway come eventi. Diversi controlli consentono di definire quali notifiche vengono inoltrate e quando.
| Chiave | Tipo | Descrizione |
|---|---|---|
notifications.allowPackages |
string[] | Inoltra solo le notifiche da questi nomi di pacchetto. Se impostato, tutti gli altri pacchetti vengono ignorati. |
notifications.denyPackages |
string[] | Non inoltrare mai notifiche da questi nomi di pacchetto. Applicato dopo allowPackages. |
notifications.quietHours.start |
string (HH:mm) | Inizio della finestra delle ore silenziose (ora locale del dispositivo). Le notifiche vengono soppresse durante questa finestra. |
notifications.quietHours.end |
string (HH:mm) | Fine della finestra delle ore silenziose. |
notifications.rateLimit |
number | Numero massimo di notifiche inoltrate per pacchetto al minuto. Le notifiche in eccesso vengono scartate. |
Il selettore delle notifiche usa anche un comportamento più sicuro per gli eventi di notifica inoltrati, impedendo l'inoltro accidentale di notifiche di sistema sensibili.
Esempio di configurazione:
{ notifications: { allowPackages: ["com.slack", "com.whatsapp"], denyPackages: ["com.android.systemui"], quietHours: { start: "22:00", end: "07:00", }, rateLimit: 5, },}