Beta: All apps in this collection are under active development. Expect bugs, breaking changes, and incomplete features. Use at your own risk.
A collection of Android apps and utilities for Google Glass Explorer Edition running AOSP 5.1.1.
All Android apps target minSdk 19 / targetSdk 19, use Java 11, AGP 8.9.0, and have no AndroidX dependencies. Built with ./gradlew assembleDebug and installed via adb install -r.
| App | Description | Network | Companion Required |
|---|---|---|---|
| glass-launcher | Custom home screen with gesture navigation | None | No |
| glass-display | Fullscreen MJPEG stream viewer | WiFi/USB | No (connects to any MJPEG source) |
| glass-kill | Kill all non-essential background processes | None | No |
| glass-monitor | Desktop screen capture → MJPEG stream | WiFi/USB | Standalone Python server |
| glass-pomodoro | Pomodoro timer (15min work / 5min break) | None | No |
| glass-stream | Camera MJPEG streaming server | WiFi/USB | Optional - Python viewer & shell scripts |
| glass-term | Terminal emulator with SSH client & favorites | None | No |
| glass-vnc | VNC remote desktop viewer with zoom modes | WiFi/USB | No (connects to any VNC server) |
| glass-stocks | StockCharts Voyeur slideshow with 3 zoom levels | WiFi/USB | No |
| glass-weather | Current conditions & hourly forecast via Open-Meteo | WiFi/USB | No |
| vesc-glass | Electric skateboard telemetry HUD | Bluetooth LE | No (connects to VESC BLE dongle) |
| glass-notify | Notification forwarder + GPS passthrough + tilt-to-wake | WiFi/USB | Yes - glass-notify-client on phone |
| glass-clawd | Voice-powered Claude AI chat client | WiFi/USB | Yes - Python proxy + Whisper server |
| glass-dashboard | News, sports scores, and stock quotes on 3 swipeable pages | WiFi/USB | No |
| glass-reader | PDF reader with book and teleprompter modes | None | No |
| glass-rss | Multi-feed RSS reader with swipeable cards | WiFi/USB | No |
| glass-bike-hud | Biking HUD with heart rate, speed, distance | Bluetooth LE | Yes - watch-bike-hud on Galaxy Watch |
| watch-bike-hud | Galaxy Watch sensor broadcaster for glass-bike-hud | Bluetooth LE | Yes - glass-bike-hud on Glass |
| glass-flipper | Flipper Zero screen mirror via USB OTG | USB OTG | No (direct USB CDC serial) |
| glass-music | Stream Linux system audio to Glass over Bluetooth | Bluetooth | Yes — Python streaming client on Linux |
| glass-obd | OBD2 car telemetry HUD with 4 swipeable data pages | Bluetooth | No (connects to ELM327 dongle) |
| glass-watch-input | BLE input bridge receiver — injects watch events as keys | Bluetooth LE | Yes — watch-input on Galaxy Watch |
| watch-input | Galaxy Watch D-pad remote control for Glass | Bluetooth LE | Yes — glass-watch-input on Glass |
Custom home screen launcher that displays installed apps in a horizontally scrolling carousel. Replaces the stock Glass launcher with gesture-driven navigation.
- Horizontal app carousel with visual selection highlight
- Status bar with date/time and battery percentage
- Tap to launch, swipe left/right to browse, swipe down to dismiss
- Two-finger tap and long-press gesture support
- Camera button remapped to Home via accessibility service (
ButtonRemapService): short press opens the camera as normal, long press returns to the launcher - Pinned apps appear first (configurable in source)
- System dialog navigator: Detects system dialogs (USB permissions, install confirmations, etc.) and shows a touchpad-navigable overlay with cyan selection highlight. Swipe left/right to cycle elements, tap or camera button to click. Solves the problem of Glass's touchpad being unable to interact with standard Android dialogs.
Permissions: SYSTEM_ALERT_WINDOW, BIND_ACCESSIBILITY_SERVICE
No network or companion required — runs entirely on-device.
Fullscreen MJPEG viewer for watching live video streams on Glass. Connects to any HTTP MJPEG source (glass-stream, glass-monitor, or any standard MJPEG server). Displays real-time FPS and connection status.
Permissions: INTERNET, WAKE_LOCK
# Via USB (requires adb reverse on host)
adb reverse tcp:8080 tcp:8080
adb shell am start -n com.glassdisplay/.MainActivity
# Via WiFi (pass host IP)
adb shell am start -n com.glassdisplay/.MainActivity --es host 192.168.1.100Gestures: Swipe down, long-press, or right-click to exit. Default port is 8080.
Quick utility that kills all non-essential background processes on Glass to free up memory. Launches, kills everything, shows results, and auto-exits after 3 seconds.
Permissions: KILL_BACKGROUND_PROCESSES
Uses both killBackgroundProcesses() (API) and am force-stop (shell) for thorough cleanup. Protects Android system, Google services, Glass system apps, and the custom launcher.
adb shell am start -n com.glasskill/.MainActivityNo network or companion required.
Python utility (not an Android app). Captures a region of your Linux desktop and streams it as MJPEG to Glass via HTTP. Creates a virtual 640x360 monitor using xrandr for proper resolution targeting.
pip install mss Pillow
Requires X11 with xrandr.
# Default: virtual GLASS monitor at bottom-right, 30fps, quality 70
python glass_monitor.py
# Custom source region
python glass_monitor.py --region 1080,1880
# Capture modes: full, quarter (1:1), half, zoom
python glass_monitor.py --mode zoom --fps 20 --quality 80
# Skip virtual monitor creation
python glass_monitor.py --no-monitor --region X,YStreams on port 8080 by default. View on Glass with glass-display.
start.sh [mode] [args...]— Clean start: kills old processes, sets up adb reverse, launches server. Default mode: zoompick-and-stream.sh [args...]— 5-second countdown to position mouse, then captures region and starts streamingpick-region.sh— Find X,Y coordinates for--regionwithout starting the serverlaunch-glass-claude.sh— Opens a terminal window sized to the GLASS monitor region
Simple Pomodoro timer for Glass. 15-minute work phases and 5-minute break phases cycling indefinitely. Large countdown display with phase label (WORK / BREAK).
Permissions: WAKE_LOCK
Controls: Tap to pause/resume. Swipe down or long-press to exit.
No network or companion required.
StockCharts Voyeur viewer for Glass. Fetches the 10 rotating community stock charts from StockCharts Voyeur and displays them as a fullscreen slideshow. Three tap-to-cycle zoom modes: Fit (full chart), Fill (center-crop), and Close-up (2.5x top-left for reading ticker symbols).
Permissions: INTERNET, WAKE_LOCK
adb shell am start -n com.glassstocks/.MainActivityControls: Tap to cycle zoom. Swipe left/right for prev/next chart. Swipe down or long-press to exit.
Auto-cycles every 10 seconds, re-fetches all images every 60 seconds. Counter overlay shows position (e.g. 3 / 10).
No companion required.
Turns Glass into an MJPEG camera streaming server. Captures from the device camera and serves the feed over HTTP on port 8080. Supports multiple simultaneous viewers.
Permissions: CAMERA, INTERNET, WAKE_LOCK, ACCESS_WIFI_STATE, ACCESS_NETWORK_STATE
http://<glass-ip>:8080/— HTML viewer pagehttp://<glass-ip>:8080/stream— Raw MJPEG streamhttp://<glass-ip>:8080/snapshot— Single JPEG frame
On-device controls: Camera button cycles JPEG quality (50% → 70% → 85%).
Python viewer with recording support:
cd glass-stream/viewer
python glass_viewer.py <glass-ip> [port]
# Keys: r=record, s=snapshot, q=quitShell scripts in glass-stream/scripts/:
./scripts/view.sh # View stream via ffplay
./scripts/deploy.sh # Build, install, and launch
./scripts/record.sh # Record stream to file
./scripts/snap.sh # Capture single frameTerminal emulator for Glass with USB keyboard support. Spawns /system/bin/sh and provides a VT100-compatible display with local echo, scrollback, and QWERTY-to-Dvorak keyboard remapping. Includes a bundled SSH client (Dropbear dbclient) with quick-connect favorites.
Permissions: None (SSH requires network access from the shell)
- 53x18 character grid sized for the 640x360 Glass display
- VT100/ANSI terminal emulation (cursor movement, colors, erase, scroll regions)
- 16-color and 256-color ANSI palette
- Local echo and line editing (no PTY)
- QWERTY and Dvorak keyboard layouts (Ctrl+K to toggle, persisted)
- 500-line scrollback buffer (Shift+PgUp/PgDn)
- Ctrl+C (interrupt), Ctrl+D (EOF), Ctrl+L (clear screen)
- Cursor blink, backspace, tab
A static ARM Dropbear dbclient binary is bundled in the APK and extracted on first launch. Five SSH favorite slots are shown in a bar at the bottom of the screen.
Keyboard shortcuts: Ctrl+1 through Ctrl+5 to connect to the corresponding favorite.
Configuring favorites via adb intent extras (persisted in SharedPreferences):
adb shell "am start -n com.example.glassterm/.TerminalActivity \
--es ssh_fav_0 'mypc|user|192.168.0.100|22' \
--es ssh_fav_1 'server|root|10.0.0.1|22'"Format: name|user|host|port
Note: The bundled Dropbear client supports public-key authentication only. Use dropbearkey to generate keys or convert existing OpenSSH keys.
Gestures: Swipe down on Glass touchpad to exit.
Limitation: Without a PTY, interactive programs like vi, less, and top won't work. Standard commands (ls, cd, cat, echo, ps, grep, etc.) all work fine.
No companion required — SSH connects directly from Glass over WiFi.
VNC (Remote Framebuffer) viewer for Glass. Connects to any VNC server using the RFB protocol and renders the remote desktop fullscreen. Supports no-auth and VNC password authentication, with Zlib, Raw, and CopyRect encodings. Only requests the viewport region for efficient bandwidth on large displays. Four zoom modes let you trade off between seeing the full desktop or readable detail.
Permissions: INTERNET, WAKE_LOCK
| Mode | Source Crop | Effect |
|---|---|---|
full |
Entire desktop | Scale whole screen to 640x360 |
quarter |
640x360 | 1:1 pixel crop (no scaling) |
half |
960x540 | Crop scaled down to 640x360 |
zoom |
1280x720 | Crop scaled down to 640x360 |
# Basic — connect to VNC server on default port 5900
adb shell am start -n com.glassvnc/.MainActivity --es host 192.168.1.100
# With password and initial zoom mode
adb shell am start -n com.glassvnc/.MainActivity --es host 192.168.1.100 --es password secret --es mode zoom
# Custom port
adb shell am start -n com.glassvnc/.MainActivity --es host 192.168.1.100 --ei port 5901Controls: Tap to cycle zoom mode. Swipe down, long-press, or back to exit. Connection settings and zoom mode persist across launches.
No companion required — connects directly to any standard VNC server.
Real-time heads-up display for electric skateboard telemetry. Connects to a VESC motor controller via Bluetooth LE (Nordic UART Service) and displays live data on Glass.
Permissions: BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_COARSE_LOCATION, WAKE_LOCK
- Speed (mph)
- Duty cycle (%)
- Battery percentage with auto cell-count detection
- Pack voltage
- MOSFET and motor temperatures (C/F)
- Trip distance
- Compass heading (8-point cardinal directions)
- Auto-connects to trusted VESC devices (persisted via SharedPreferences)
- Device picker for new VESCs (shows name + MAC suffix)
- Color-coded warnings: green (OK), yellow (caution), red (critical)
- 200ms polling interval
- Long-press [X] to forget a trusted device
Default parameters in VescProtocol.java:
Motor poles: 30
Wheel diameter: 280mm
Gear ratio: 1.0
Cell count: auto-detect
Cell full: 4.2V / Cell empty: 3.0V
No companion required — connects directly to the VESC BLE dongle.
Real-time car telemetry heads-up display. Connects to an ELM327 OBD2 Bluetooth dongle over classic Bluetooth RFCOMM and streams live engine data across four swipeable pages.
Permissions: BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_COARSE_LOCATION, WAKE_LOCK
| Page | Hero Metric | Supporting Data |
|---|---|---|
| Drive | Speed (mph) | RPM, throttle %, coolant temp, engine load, voltage |
| Engine | RPM | Speed, throttle %, coolant temp, intake air temp, timing advance, MAF rate |
| Fuel | Fuel level (%) | Fuel rate (L/h), fuel system status, fuel pressure, short/long-term fuel trims |
| Diag | DTC count | MIL status, engine runtime, distance since codes cleared, voltage |
Polls up to 17 PIDs depending on vehicle support: 01 (monitor status), 03 (fuel system), 04 (load), 05 (coolant), 06/07 (fuel trims), 0A (fuel pressure), 0C (RPM), 0D (speed), 0E (timing), 0F (intake air), 10 (MAF), 11 (throttle), 1F (runtime), 2F (fuel level), 31 (distance since clear), 42 (voltage), 5E (fuel rate). Supported PIDs are auto-detected via 0100/0120/0140 queries.
ATZ → ATE0 → ATL0 → ATS0 → ATSP0 (auto protocol detect)
- Auto-discovers ELM327 dongles (filters by name: OBD, ELM, VEEPEAK, KONNWEI, V-LINK, SCAN)
- Auto-pairs with PIN 1234 (standard ELM327 PIN)
- 3-strategy RFCOMM fallback: secure → insecure → reflection channel 1
- Trusted device persistence (auto-reconnects across app restarts)
- ECU detection with retry — shows "NO ECU — IGNITION OFF?" when car isn't running
- Color-coded warnings: speed (white→yellow@60→red@80 mph), RPM (white→yellow@4000→red@5500), coolant (dim→yellow@200→red@220°F), fuel level (white→yellow@25→red@10%), fuel trims (dim→yellow@10→red@20%)
- Page indicator dots and label at bottom of screen
| Input | Action |
|---|---|
| Swipe left/right | Switch page |
| Tap | Reconnect |
| Long-press | Exit |
| Swipe down | Exit |
| [X] tap | Exit |
| [X] long-press | Forget trusted adapters + rescan |
| Back / Escape | Exit |
adb install -r apks/glass-obd.apk
adb shell am start -n com.glassobd/.MainActivityNo companion required — connects directly to any ELM327 OBD2 Bluetooth dongle.
Phone-to-Glass notification forwarding system with GPS passthrough and tilt-to-wake. Two apps work together: a phone companion (glass-notify-client) captures notifications and GPS, and the Glass app (glass-notify) receives and displays them.
Permissions (Glass): INTERNET, WAKE_LOCK, ACCESS_WIFI_STATE, ACCESS_FINE_LOCATION, ACCESS_MOCK_LOCATION
- Notification forwarding: Phone notifications appear on Glass with app name, title, and body. Screen wakes for 8 seconds per notification. History view holds last 50 entries.
- GPS passthrough: Phone GPS is forwarded to Glass as a mock location provider. Any app using
LocationManager.GPS_PROVIDER(e.g. glass-weather) automatically gets real coordinates. - Tilt-to-wake: Accelerometer-based head-tilt detection wakes the Glass screen when you look up. 300ms sustain threshold, 2-second cooldown, rejects motion and sideways tilt.
Length-prefixed JSON over TCP port 9876:
Notification: {"type":"notification","app":"Gmail","title":"New mail","text":"...","time":123}
Location: {"type":"location","lat":35.08,"lon":-106.65,"alt":1600,"acc":10,"time":123}
Heartbeat: {}
- Install
glass-notifyon Glass,glass-notify-clienton phone - Enable mock locations on Glass (one-time):
adb shell settings put secure mock_location 1
- Launch glass-notify on Glass — note the IP:port shown on screen
- Launch glass-notify-client on phone, enter Glass IP, tap Start
- Grant notification access and location permissions when prompted
Voice assistant client for Claude AI on Glass. Records audio locally via AudioRecord (16kHz 16-bit mono), sends the WAV to a companion server which transcribes with faster-whisper and forwards the text to Claude — returning both the transcription and response in a single round-trip. Auto-restarts recording after each response for continuous conversation.
Permissions: INTERNET, RECORD_AUDIO
Controls: Tap or camera button to start/stop recording. Swipe up/down to scroll chat.
cd glass-clawd/server
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
echo 'ANTHROPIC_API_KEY=sk-ant-...' > .env && chmod 600 .env
python server.py # default: base Whisper model
python server.py --model small # or: tiny, base, small, mediumEndpoints:
GET /— Chat web UIGET /history— Conversation history (JSON)POST /chat— Text input →{"reply": "..."}POST /voice— Multipart WAV audio →{"transcription": "...", "reply": "..."}POST /clear— Reset conversation
Note: The server IP is hardcoded in MainActivity.java. Update it to match your host machine's IP.
Information dashboard for Glass with three swipeable pages: news headlines, live sports scores, and stock quotes. All data comes from free, no-API-key sources.
Permissions: INTERNET, WAKE_LOCK
| Page | Source | Refresh |
|---|---|---|
| News | Google News RSS (via feed2json) | 15 min |
| Sports | ESPN hidden API (NFL, NBA, MLB, NHL) | 5 min |
| Stocks | Yahoo Finance quotes | 5 min |
# Launch with default stock watchlist (AAPL, MSFT, GOOGL, AMZN, TSLA, META, NVDA, SPY, QQQ, DIA)
adb shell am start -n com.glassdashboard/.MainActivity
# Custom stock watchlist (persisted across launches)
adb shell am start -n com.glassdashboard/.MainActivity --es symbols "AAPL,GME,BTC-USD"Controls: Swipe left/right to switch pages. Tap to refresh current page. Swipe down, long-press, or back to exit.
No companion required.
PDF reader for Glass. Extracts text from PDFs using PdfBox-Android and displays as paginated readable text on the 640x360 display. Two reading modes: book mode (swipe through pages) and teleprompter mode (auto-scrolling text that starts at a comfortable reading pace).
Permissions: READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
adb shell mkdir -p /sdcard/glass-reader
adb push mybook.pdf /sdcard/glass-reader/If only one PDF is present, it opens automatically. Multiple PDFs show a file picker.
| Mode | Gesture | Action |
|---|---|---|
| Picker | Swipe fwd/back | Select file |
| Picker | Tap | Open file |
| Book | Swipe fwd/back | Next/prev page |
| Book | Tap | Switch to teleprompter |
| Book | Long press | Toggle status bar |
| Teleprompter | Swipe forward | Speed up |
| Teleprompter | Swipe backward | Slow down |
| Teleprompter | Tap | Switch to book |
| Teleprompter | Long press | Pause/resume |
| All | Swipe down | Exit |
Reading position, scroll offset, and mode are saved per file and restored on relaunch.
No network or companion required.
Multi-feed RSS reader for Glass. Fetches multiple RSS/Atom feeds in parallel, merges and sorts all items by date, and displays them as horizontally swipeable cards. Auto-detects RSS 2.0 and Atom formats.
Permissions: INTERNET, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
- Hacker News (Front Page)
- Ars Technica
- The Verge
- Yahoo Finance (S&P 500 news)
- Yahoo Finance (AAPL, MSFT, GOOG, NVDA news)
Feed URLs are read from /sdcard/glass-rss-feeds.txt (one URL per line, # for comments). The file is auto-created with defaults if missing. Edit it to customize:
adb shell "echo 'https://hnrss.org/frontpage' > /sdcard/glass-rss-feeds.txt"adb shell am start -n com.example.glassrss/.RssActivityControls: Swipe left/right to browse cards. Swipe down to exit. Long-press to refresh. Auto-refreshes every 15 minutes. Fetches up to 20 items per feed.
No companion required.
Current weather conditions and hourly forecast for Glass. Uses the free Open-Meteo API — no API key needed. Displays large current temperature, condition, wind speed, humidity, and a horizontally scrollable hourly forecast.
Permissions: INTERNET, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, WAKE_LOCK
# Launch with default location (Albuquerque, NM)
adb shell am start -n com.glassweather/.MainActivity
# Set location by city name (resolved via geocoding, persisted across launches)
adb shell am start -n com.glassweather/.MainActivity --es city "Denver, CO"
# Launch with custom coordinates
adb shell am start -n com.glassweather/.MainActivity --ef lat 40.7128 --ef lon -74.0060Controls: Tap to refresh. Swipe down or long-press to exit.
Location priority: City name intent → lat/lon intent → saved location (SharedPreferences) → GPS/network → default (Albuquerque, NM). City names are resolved via the Open-Meteo geocoding API and persisted, so subsequent launches remember the location.
Auto-refreshes every 15 minutes. When glass-notify is running with GPS passthrough, glass-weather automatically uses the phone's real location.
No companion required (but benefits from glass-notify GPS passthrough).
Biking heads-up display that receives heart rate, GPS speed, distance, and elapsed time from a Galaxy Watch over Bluetooth LE. The watch runs a companion app (watch-bike-hud) that acts as a BLE GATT server, streaming sensor data in real-time. Glass acts as a receive-only BLE GATT client — no polling, the watch pushes all data via notifications.
Permissions: BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_COARSE_LOCATION, WAKE_LOCK
┌──────────────────────────────────────┐
│ 14.2 mph [X] │
│ mph │
│ ♥ 142 │
│ bpm │
│ 3.42 mi 00:45:12 CONNECTED │
└──────────────────────────────────────┘
- Center: Heart rate (hero metric, 72sp bold, color-coded by HR zone)
- Top-left: Speed in mph (56sp bold, color-coded)
- Bottom-left: Trip distance (miles)
- Bottom-center: Elapsed ride time (HH:MM:SS)
- Bottom-right: BLE connection status
- Top-right: [X] close button
| Metric | Green | Yellow | Red |
|---|---|---|---|
| Heart rate | < 130 bpm | 130–160 bpm | > 160 bpm |
| Speed | — (white) | > 20 mph | > 30 mph |
Custom GATT service 0000ff10-... with three notify characteristics:
| Characteristic | UUID | Format |
|---|---|---|
| Heart Rate | 0000ff11-... |
1 byte: bpm (uint8) |
| Location | 0000ff12-... |
24 bytes: lat(f64) + lon(f64) + speed_mps(f32) + bearing(f32) |
| Trip | 0000ff13-... |
8 bytes: distance_m(f32) + elapsed_s(uint32) |
- Auto-discovers watches advertising the bike HUD service UUID
- Trusted device persistence (auto-reconnects across app restarts)
- Single device auto-trust, picker UI for multiple watches
- Queued CCCD descriptor writes for reliable characteristic subscription
- Auto-reconnect on disconnect (rescan after 2s)
| Input | Action |
|---|---|
| Tap | Reconnect (stop + rescan) |
| Long-press | Exit |
| Swipe down | Exit |
| [X] tap | Exit |
| [X] long-press | Forget trusted watches + rescan |
| Back / Escape | Exit |
# Build and install on Glass
cd glass-bike-hud && ./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apkRequires watch-bike-hud running on a Galaxy Watch.
Wear OS companion app for glass-bike-hud. Runs on Galaxy Watch 4/5/6/7 as a foreground service, reading the heart rate sensor and GPS, then broadcasting all data to Glass via BLE GATT notifications. The watch acts as a BLE GATT peripheral (server); Glass connects as the client.
Platform: Wear OS, Kotlin, minSdk 30, targetSdk 34, Java 17
Permissions: BODY_SENSORS, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, FOREGROUND_SERVICE, FOREGROUND_SERVICE_HEALTH, WAKE_LOCK, POST_NOTIFICATIONS
WatchBikeActivity (UI: start/stop, current stats)
└── BikeSensorService (Foreground Service)
├── SensorManager → TYPE_HEART_RATE
├── FusedLocationProviderClient → GPS (1s interval, HIGH_ACCURACY)
├── DistanceTracker → accumulates GPS distance with jitter filter
└── BleGattServer → advertise + notify connected clients
- Heart rate: Android
TYPE_HEART_RATEsensor, filters unreliable readings, pushes via BLE on each change - GPS: Google Play Services FusedLocation, 1s interval / 500ms fastest, pushes lat/lon/speed/bearing
- Distance: Accumulates
Location.distanceTo()with jitter filter — rejects < 2m (noise) and > 100m (teleports), ignores points with > 20m accuracy - Elapsed time: Counts from service start, updates every 1s
Advertises custom service UUID 0000ff10-... with LOW_LATENCY mode and HIGH TX power. Supports multiple concurrent Glass connections. All three characteristics are notify-only with proper CCCD descriptor handling.
Simple dark screen showing current HR, GPS status, BLE connection count, distance, elapsed time, and a START/STOP button to control the foreground service.
# Build
cd watch-bike-hud && ./gradlew assembleDebug
# Install via ADB over WiFi to watch
adb connect <watch-ip>:5555
adb -s <watch-ip>:5555 install -r app/build/outputs/apk/debug/app-debug.apk- Launch on watch, grant all permissions (body sensors, location, BLE, notifications)
- Tap START — foreground notification appears, BLE advertising begins
- Launch glass-bike-hud on Glass — auto-discovers and connects
- Tap STOP to end the session
com.google.android.gms:play-services-location:21.0.1(FusedLocation)com.google.android.wearable:wearable:2.9.0(compileOnly)
Mirrors the Flipper Zero's 128x64 monochrome OLED display onto Glass in real-time over USB OTG. Connects via USB CDC serial, starts a Protobuf RPC session, and streams screen frames at ~18fps with pixel-perfect 5x nearest-neighbor scaling.
Permissions: WAKE_LOCK, USB_HOST
Plug the Flipper into Glass via USB OTG cable — the app auto-launches. Navigate the Flipper normally and its screen appears on Glass.
First-time setup: Glass shows a USB permission dialog that can't be tapped via touchpad. Use ADB over WiFi to approve it remotely:
# Enable WiFi ADB while Glass is on USB
adb tcpip 5555
adb connect $(adb shell ip addr show wlan0 | grep -oP '(?<=inet )\S+(?=/)'):.5555
# Unplug Glass, plug in Flipper via OTG, then tap OK remotely:
adb -s <glass-ip>:5555 shell input tap 148 270 # tick "Use by default"
adb -s <glass-ip>:5555 shell input tap 476 322 # tap OKAfter checking "Use by default", future connections are automatic.
Gestures: Swipe down or back to exit.
No companion required — connects directly via USB.
Streams Linux system audio to Glass's bone conduction speaker over Bluetooth RFCOMM. A Python client captures all system audio output via PulseAudio (parec) and streams 44.1kHz mono 16-bit PCM to Glass in real-time (~706 kbps). Glass pre-fills the AudioTrack buffer before starting playback to eliminate underruns.
Permissions: BLUETOOTH, BLUETOOTH_ADMIN, WAKE_LOCK
Length-prefixed typed frames: [4-byte BE length][1-byte type][body]
| Type | Direction | Content |
|---|---|---|
0x01 CONFIG |
Linux→Glass | JSON: sample rate, channels, encoding |
0x02 AUDIO |
Linux→Glass | Raw PCM bytes (4096-byte chunks) |
0x03 COMMAND |
Glass→Linux | JSON: pause/resume |
0x04 HEARTBEAT |
Both | No body |
# Stream system audio to Glass
python3 linux/glass_music.py <glass-mac> -c 5
# Auto-detect channel (slower)
python3 linux/glass_music.py <glass-mac>
# Custom audio source
python3 linux/glass_music.py <glass-mac> -d <pulse-monitor-source>Controls: Tap to pause/resume. Swipe down to exit. Long-press for discoverability.
Linux requirements: Python 3, PulseAudio (parec). Optional PyBluez for SDP lookup.
BLE input bridge for Glass. Runs as an AccessibilityService, connects to a Galaxy Watch running watch-input over Bluetooth LE, and injects received input events as system-wide key events. System keys (Home, Back, Menu) use performGlobalAction(). D-pad keys are injected via a root key bridge daemon that reads from a FIFO.
Permissions: BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_COARSE_LOCATION
Important: Must be installed as a priv-app (/system/priv-app/). Requires a one-time setup of the root key bridge daemon for D-pad injection.
| Watch Input | Glass Action |
|---|---|
| D-Pad directions | DPAD_UP/DOWN/LEFT/RIGHT (via root daemon) |
| OK (center) | DPAD_CENTER (via root daemon) |
| Rotary CW/CCW | DPAD_RIGHT/LEFT (via root daemon) |
| Tap gesture | DPAD_CENTER (via root daemon) |
| Swipe gestures | DPAD_LEFT/RIGHT/UP/DOWN (via root daemon) |
| Long press | Back (global action) |
| Home / Back / Menu | Global actions (no extra permissions needed) |
Android's INJECT_EVENTS permission is signature-only — even priv-apps can't get it. The solution is a root daemon that starts on boot:
Watch → BLE → InputBridgeService → writes to FIFO → root daemon → input keyevent
The daemon runs as root via init's flash_recovery service, reading key codes from /data/local/tmp/keybridge.
Use the setup script for a fully automated install:
cd glass-watch-input
./setup.shThis builds the APK, installs it as a priv-app, sets up the root key bridge daemon, enables the accessibility service, and reboots Glass. See the glass-watch-input README for manual setup and troubleshooting.
Custom GATT service 0000ff20-... with a single notify characteristic (0000ff21-...). 4-byte payloads:
| Byte | Field | Values |
|---|---|---|
| 0 | Type | 0x01 KEY, 0x02 GESTURE, 0x03 ROTARY |
| 1 | Value | Gesture/rotary ID or Android keycode |
| 2 | Action | 0x00 DOWN, 0x01 UP (keys only) |
| 3 | Reserved | 0x00 |
Requires watch-input running on a Galaxy Watch.
Wear OS remote control app for Glass. Displays a D-pad with directional buttons (up/down/left/right/OK) and system buttons (Back, Home, Menu). Sends all input to Glass over BLE using a GATT server. Also forwards hardware stem button presses and rotary encoder input.
Platform: Wear OS, Kotlin, minSdk 30, targetSdk 34, Java 17
Permissions: BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, FOREGROUND_SERVICE, FOREGROUND_SERVICE_CONNECTED_DEVICE, WAKE_LOCK, POST_NOTIFICATIONS
[ UP ]
[LEFT] [ OK ] [RIGHT]
[ DOWN ]
[BACK] [HOME] [MENU]
- D-Pad buttons send gesture events (mapped to DPAD keys on Glass)
- System buttons send key down+up pairs (BACK, HOME, MENU)
- Rotary encoder sends CW/CCW events
- Stem buttons forwarded as raw key events
# Build
cd watch-input && ./gradlew assembleDebug
# Install on watch via WiFi ADB
adb connect <watch-ip>:5555
adb -s <watch-ip>:5555 install -r app/build/outputs/apk/debug/app-debug.apk- Launch on watch — BLE advertising starts automatically
- Enable glass-watch-input accessibility service on Glass
- Glass auto-connects to the watch
- Use the on-screen buttons to control Glass remotely
com.google.android.wearable:wearable:2.9.0(compileOnly)
Requires glass-watch-input running on Glass.
Pre-built debug APKs for all apps are in the apks/ directory.
The easiest way to install is with the interactive installer — it walks through each app with a description and lets you pick which ones to install:
./install.sh # interactive — pick apps with y/n
./install.sh -y # install everything without prompting
./install.sh -h # list all apps with descriptionsOr install individual APKs manually:
adb install -r apks/glass-launcher.apkFor watch apps, install via WiFi ADB to the watch:
adb connect <watch-ip>:5555
adb -s <watch-ip>:5555 install -r apks/watch-input.apkEach Android app is a standalone Gradle project. To build any app:
cd <app-name>
./gradlew assembleDebugThe APK will be at app/build/outputs/apk/debug/app-debug.apk.
To install on Glass:
adb install -r app/build/outputs/apk/debug/app-debug.apk- Android SDK with API 34 (compileSdk) and API 19 (targetSdk)
- Java 11
- Gradle (wrapper included in each project)
Set your SDK path in local.properties:
sdk.dir=/path/to/your/android-sdk