An Android app that enables LLM control of Android devices through the OpenClaw gateway. This node connects to an OpenClaw gateway via WebSocket and exposes device capabilities like screen capture, UI interaction, and app launching.
- Accessibility Service: Read UI hierarchy and inject touch events
- Screen Capture: Take screenshots using MediaProjection API
- WebSocket Connection: Connect to OpenClaw gateway as a node
- Device Control: Support for tap, swipe, type, press, and launch commands
- Secure Authentication: RSA key-based device identity and signing
| Command | Description | Parameters |
|---|---|---|
screenshot |
Capture screen as base64 PNG | None |
ui_tree |
Get accessibility node hierarchy | None |
tap(x, y) |
Perform tap at coordinates | x, y (float) |
swipe(x1, y1, x2, y2, duration) |
Perform swipe gesture | x1, y1, x2, y2 (float), durationMs (long) |
type(text) |
Type text into focused input | text (string) |
press(key) |
Press system keys | key: "back", "home", "recents" |
launch(package) |
Launch app by package name | packageName (string) |
- Android 8.0 (API level 26) or higher
- OpenClaw Gateway running on accessible network
- Device permissions for:
- Accessibility Service (for UI control)
- Screen Capture (for screenshots)
- System Alert Window (for overlay permissions)
cd ~/projects/openclaw-android-node
./gradlew assembleDebug
adb install app/build/outputs/apk/debug/app-debug.apk- Open the OpenClaw Node app
- Enter your Gateway host (IP address)
- Enter Gateway port (default: 18789)
- Enter Gateway token if authentication is required
- Set a display name for this node
- Tap "Save Settings"
- Tap "Enable Accessibility Service"
- Find "OpenClaw Node" in the accessibility services list
- Enable the service
- Accept the permission dialog
- Tap "Grant Screen Capture Permission"
- Accept the media projection permission dialog
- The screen capture service will start in the background
- Tap "Connect" to establish WebSocket connection
- Wait for "Connected" status
- Check OpenClaw gateway logs for node pairing request
- Approve the node from gateway CLI:
openclaw nodes approve <requestId>
From your OpenClaw gateway, verify the node is connected:
openclaw nodes status
openclaw nodes describe --node "Android Node"- Kotlin - Primary language
- Jetpack Compose - Modern UI toolkit
- Ktor Client - WebSocket communication
- Kotlinx Serialization - JSON parsing
- BouncyCastle - Cryptographic operations
- DataStore - Settings persistence
app/src/main/java/com/openclaw/node/
├── MainActivity.kt # Main UI activity
├── models/ # Data models
│ └── Protocol.kt # OpenClaw protocol models
├── services/ # Background services
│ ├── OpenClawAccessibilityService.kt # UI interaction
│ ├── ScreenCaptureService.kt # Screen capture
│ └── NodeConnectionService.kt # WebSocket connection
├── ui/ # UI components
│ ├── MainViewModel.kt # UI state management
│ └── theme/ # Material Design theme
└── utils/ # Utility classes
├── PreferencesManager.kt # Settings storage
└── CryptoUtils.kt # Device identity & signing
The node implements the OpenClaw WebSocket protocol v3:
- Handshake: Connect with device identity and capabilities
- Authentication: RSA signature-based device verification
- Command Processing: Handle incoming RPC requests
- Response: Return command results or errors
- Reads UI hierarchy using Android accessibility APIs
- Performs gestures via
GestureDescription - Handles text input to focused elements
- Manages system navigation (back, home, recents)
- Uses MediaProjection for screen recording permission
- Captures screenshots via ImageReader
- Converts images to base64 PNG format
- Runs as foreground service for continuous availability
- Maintains WebSocket connection to gateway
- Handles OpenClaw protocol messages
- Routes commands to appropriate handlers
- Manages device pairing and authentication
- Device identity generated from stable hardware characteristics
- RSA-2048 keypair for signing and verification
- Private keys stored in encrypted SharedPreferences
- Challenge-response authentication with gateway
- No sensitive data in backups (excluded via backup rules)
-
WebSocket connection failed
- Verify gateway host/port are correct
- Check network connectivity
- Ensure gateway is running and accessible
- Check gateway logs for connection attempts
-
Permission denied errors
- Verify accessibility service is enabled
- Check screen capture permission was granted
- Ensure app has overlay permission if needed
-
Commands not working
- Check accessibility service is still enabled
- Verify screen capture service is running
- Review app logs for error messages
- Test basic connectivity with gateway
- Screen capture resolution can be adjusted for faster transmission
- UI tree queries may be slow on complex layouts
- WebSocket connection uses heartbeat to maintain connection
- Services run in foreground to prevent battery optimization killing
Enable debug logging and check Android Studio Logcat:
adb logcat | grep -E "(OpenClaw|NodeConnection|ScreenCapture|AccessibilityService)"- Fork the repository
- Create a feature branch
- Make your changes
- Test on real device
- Submit a pull request
This project is part of the OpenClaw ecosystem. See the main OpenClaw repository for licensing information.