## OpenClaw Android App Status: **extremely alpha**. The app is actively being rebuilt from the ground up. ### Rebuild Checklist - [x] New 4-step onboarding flow - [x] Connect tab with `Setup Code` + `Manual` modes - [x] Encrypted persistence for gateway setup/auth state - [x] Chat UI restyled - [x] Settings UI restyled and de-duplicated (gateway controls moved to Connect) - [x] QR code scanning in onboarding - [x] Performance improvements - [x] Streaming support in chat UI - [x] Request camera/location and other permissions in onboarding/settings flow - [x] Push notifications for gateway/chat status updates - [x] Security hardening (biometric lock, token handling, safer defaults) - [x] Voice tab full functionality - [x] Screen tab full functionality - [ ] Full end-to-end QA and release hardening ## Open in Android Studio - Open the folder `apps/android`. ## Build / Run ```bash cd apps/android ./gradlew :app:assembleDebug ./gradlew :app:installDebug ./gradlew :app:testDebugUnitTest ``` ## Kotlin Lint + Format ```bash pnpm android:lint pnpm android:format ``` Android framework/resource lint (separate pass): ```bash pnpm android:lint:android ``` Direct Gradle tasks: ```bash cd apps/android ./gradlew :app:ktlintCheck :benchmark:ktlintCheck ./gradlew :app:ktlintFormat :benchmark:ktlintFormat ./gradlew :app:lintDebug ``` `gradlew` auto-detects the Android SDK at `~/Library/Android/sdk` (macOS default) if `ANDROID_SDK_ROOT` / `ANDROID_HOME` are unset. ## Macrobenchmark (Startup + Frame Timing) ```bash cd apps/android ./gradlew :benchmark:connectedDebugAndroidTest ``` Reports are written under: - `apps/android/benchmark/build/reports/androidTests/connected/` ## Perf CLI (low-noise) Deterministic startup measurement + hotspot extraction with compact CLI output: ```bash cd apps/android ./scripts/perf-startup-benchmark.sh ./scripts/perf-startup-hotspots.sh ``` Benchmark script behavior: - Runs only `StartupMacrobenchmark#coldStartup` (10 iterations). - Prints median/min/max/COV in one line. - Writes timestamped snapshot JSON to `apps/android/benchmark/results/`. - Auto-compares with previous local snapshot (or pass explicit baseline: `--baseline `). Hotspot script behavior: - Ensures debug app installed, captures startup `simpleperf` data for `.MainActivity`. - Prints top DSOs, top symbols, and key app-path clues (Compose/MainActivity/WebView). - Writes raw `perf.data` path for deeper follow-up if needed. ## Run on a Real Android Phone (USB) 1) On phone, enable **Developer options** + **USB debugging**. 2) Connect by USB and accept the debugging trust prompt on phone. 3) Verify ADB can see the device: ```bash adb devices -l ``` 4) Install + launch debug build: ```bash pnpm android:install pnpm android:run ``` If `adb devices -l` shows `unauthorized`, re-plug and accept the trust prompt again. ### USB-only gateway testing (no LAN dependency) Use `adb reverse` so Android `localhost:18789` tunnels to your laptop `localhost:18789`. Terminal A (gateway): ```bash pnpm openclaw gateway --port 18789 --verbose ``` Terminal B (USB tunnel): ```bash adb reverse tcp:18789 tcp:18789 ``` Then in app **Connect → Manual**: - Host: `127.0.0.1` - Port: `18789` - TLS: off ## Hot Reload / Fast Iteration This app is native Kotlin + Jetpack Compose. - For Compose UI edits: use Android Studio **Live Edit** on a debug build (works on physical devices; project `minSdk=31` already meets API requirement). - For many non-structural code/resource changes: use Android Studio **Apply Changes**. - For structural/native/manifest/Gradle changes: do full reinstall (`pnpm android:run`). - Canvas web content already supports live reload when loaded from Gateway `__openclaw__/canvas/` (see `docs/platforms/android.md`). ## Connect / Pair 1) Start the gateway (on your main machine): ```bash pnpm openclaw gateway --port 18789 --verbose ``` 2) In the Android app: - Open the **Connect** tab. - Use **Setup Code** or **Manual** mode to connect. 3) Approve pairing (on the gateway machine): ```bash openclaw devices list openclaw devices approve ``` More details: `docs/platforms/android.md`. ## Permissions - Discovery: - Android 13+ (`API 33+`): `NEARBY_WIFI_DEVICES` - Android 12 and below: `ACCESS_FINE_LOCATION` (required for NSD scanning) - Foreground service notification (Android 13+): `POST_NOTIFICATIONS` - Camera: - `CAMERA` for `camera.snap` and `camera.clip` - `RECORD_AUDIO` for `camera.clip` when `includeAudio=true` ## Integration Capability Test (Preconditioned) This suite assumes setup is already done manually. It does **not** install/run/pair automatically. Pre-req checklist: 1) Gateway is running and reachable from the Android app. 2) Android app is connected to that gateway and `openclaw nodes status` shows it as paired + connected. 3) App stays unlocked and in foreground for the whole run. 4) Open the app **Screen** tab and keep it active during the run (canvas/A2UI commands require the canvas WebView attached there). 5) Grant runtime permissions for capabilities you expect to pass (camera/mic/location/notification listener/location, etc.). 6) No interactive system dialogs should be pending before test start. 7) Canvas host is enabled and reachable from the device (do not run gateway with `OPENCLAW_SKIP_CANVAS_HOST=1`; startup logs should include `canvas host mounted at .../__openclaw__/`). 8) Local operator test client pairing is approved. If first run fails with `pairing required`, approve latest pending device pairing request, then rerun: 9) For A2UI checks, keep the app on **Screen** tab; the node now auto-refreshes canvas capability once on first A2UI reachability failure (TTL-safe retry). ```bash openclaw devices list openclaw devices approve --latest ``` Run: ```bash pnpm android:test:integration ``` Optional overrides: - `OPENCLAW_ANDROID_GATEWAY_URL=ws://...` (default: from your local OpenClaw config) - `OPENCLAW_ANDROID_GATEWAY_TOKEN=...` - `OPENCLAW_ANDROID_GATEWAY_PASSWORD=...` - `OPENCLAW_ANDROID_NODE_ID=...` or `OPENCLAW_ANDROID_NODE_NAME=...` What it does: - Reads `node.describe` command list from the selected Android node. - Invokes advertised non-interactive commands. - Skips `screen.record` in this suite (Android requires interactive per-invocation screen-capture consent). - Asserts command contracts (success or expected deterministic error for safe-invalid calls like `sms.send` and `notifications.actions`). Common failure quick-fixes: - `pairing required` before tests start: - approve pending device pairing (`openclaw devices approve --latest`) and rerun. - `A2UI host not reachable` / `A2UI_HOST_NOT_CONFIGURED`: - ensure gateway canvas host is running and reachable, keep the app on the **Screen** tab. The app will auto-refresh canvas capability once; if it still fails, reconnect app and rerun. - `NODE_BACKGROUND_UNAVAILABLE: canvas unavailable`: - app is not effectively ready for canvas commands; keep app foregrounded and **Screen** tab active. ## Contributions This Android app is currently being rebuilt. Maintainer: @obviyus. For issues/questions/contributions, please open an issue or reach out on Discord.