71 lines
4.1 KiB
Markdown
71 lines
4.1 KiB
Markdown
|
|
# IrisGlass (Glass XE24 BLE Central)
|
|||
|
|
|
|||
|
|
Android app for Google Glass Explorer Edition (XE24, Android 4.4.2 / API 19) that connects as a BLE Central (GATT client) to an iPhone Peripheral and renders a “Google Now style feed” winner on a pinned LiveCard.
|
|||
|
|
|
|||
|
|
## What it does
|
|||
|
|
- Scans using legacy BLE APIs (`BluetoothAdapter.startLeScan`) with a 10s timeout.
|
|||
|
|
- Connects + discovers the custom service:
|
|||
|
|
- `A0B0C0D0-E0F0-4A0B-9C0D-0E0F1A2B3C4D`
|
|||
|
|
- Subscribes to notifications on `FEED_TX` by writing the CCCD (0x2902).
|
|||
|
|
- Reassembles chunked notifications into a UTF-8 JSON `FeedEnvelope` and logs it.
|
|||
|
|
- Parses JSON with `org.json` into a minimal model: winner title/subtitle + “+N”.
|
|||
|
|
- Shows status (“Scanning…/Connecting…/Connected” or last error) on a persistent LiveCard pinned near the clock.
|
|||
|
|
- Tapping the LiveCard opens a swipeable feed view (CardScrollView) with per-card actions (dismiss/snooze/save).
|
|||
|
|
|
|||
|
|
Logcat tags:
|
|||
|
|
- `BLE` scan/connect/subscribe
|
|||
|
|
- `FEED` reassembly + parsing
|
|||
|
|
- `HUD` LiveCard lifecycle + rendering
|
|||
|
|
|
|||
|
|
## Using the feed UI
|
|||
|
|
- Tap the pinned LiveCard to open `FeedActivity`.
|
|||
|
|
- Swipe left/right to move through cards.
|
|||
|
|
- Tap a card to open its actions (Glass-style overlay); `DISMISS` / `SNOOZE_*` are stored locally and stay hidden across restarts.
|
|||
|
|
|
|||
|
|
## FYI static cards (Weather)
|
|||
|
|
If the feed includes a card with `bucket="FYI"` and a `type` that equals `WEATHER_INFO` or contains `WEATHER` (e.g. `CURRENT_WEATHER`), the app publishes it as a Glass “static card” via an Android notification using a custom `RemoteViews` layout modeled after the “Google Now Weather” card style (see `app/src/main/res/layout/weather_static_card.xml` and `app/src/main/java/sh/nym/irisglass/WeatherStaticCardPublisher.java`).
|
|||
|
|
|
|||
|
|
## Notification framing (FeedReassembler)
|
|||
|
|
`FEED_TX` notifications are treated as either:
|
|||
|
|
- **FEED_TX frame (primary)**:
|
|||
|
|
- `[0..3]=msgId(u32 LE)`
|
|||
|
|
- `[4]=msgType(u8: 1=FULL_FEED, 2=PING)`
|
|||
|
|
- `[5..6]=chunkIndex(u16 LE, 0-based)`
|
|||
|
|
- `[7..8]=chunkCount(u16 LE)`
|
|||
|
|
- `[9..]=payload bytes (UTF-8 slice)`
|
|||
|
|
- **Binary V1**: `[type:1][msgId:4 LE][totalLen:4 LE][offset:4 LE][utf8-bytes...]` (type `0x01`=feed, `0x02`=ping)
|
|||
|
|
- **Binary V2**: `[type:1][msgId:2 LE][chunkIndex:2 LE][totalChunks:2 LE][utf8-bytes...]` (type `0x01`=feed, `0x02`=ping)
|
|||
|
|
- **ASCII fallback**: if the payload contains a `{...}` JSON object, it is parsed directly; `PING`/`ping` updates last ping time.
|
|||
|
|
|
|||
|
|
## Build setup (Glass GDK LiveCard)
|
|||
|
|
This project uses the Glass GDK `LiveCard` APIs directly (see `app/src/main/java/sh/nym/irisglass/HudService.java`) and renders the pinned HUD using `LiveCard.setViews(...)` with a `RemoteViews` layout (`app/src/main/res/layout/hud_live_card.xml`).
|
|||
|
|
|
|||
|
|
If you prefer compiling directly against the Glass Development Kit Preview add-on:
|
|||
|
|
1. Install the SDK add-on: **Google Inc. → Glass Development Kit Preview (API 19)** in the Android SDK Manager.
|
|||
|
|
2. Set the module `compileSdk` to the add-on in `app/build.gradle` (or via Android Studio Project Structure).
|
|||
|
|
|
|||
|
|
## Install on Glass
|
|||
|
|
1. Enable developer mode + ADB on Glass.
|
|||
|
|
2. Connect over USB and verify:
|
|||
|
|
- `adb devices`
|
|||
|
|
3. Install:
|
|||
|
|
- `./gradlew :app:installDebug`
|
|||
|
|
4. Launch “Iris Glass” on Glass.
|
|||
|
|
|
|||
|
|
Expected behavior:
|
|||
|
|
- Within ~15 seconds (scan + connect), the LiveCard status should reach “Connected”.
|
|||
|
|
- On the first full feed, `FEED` logs a reassembled JSON string.
|
|||
|
|
- The LiveCard displays the winner title/subtitle and a “+N” indicator for remaining items.
|
|||
|
|
- Tap the LiveCard to open the full feed and swipe through cards (Google Now style).
|
|||
|
|
|
|||
|
|
## Troubleshooting
|
|||
|
|
- **No scan results**:
|
|||
|
|
- Ensure Bluetooth is ON on Glass.
|
|||
|
|
- Ensure the iPhone is advertising and within range.
|
|||
|
|
- Some Android builds require location permission for BLE scan; this app declares `ACCESS_COARSE_LOCATION`.
|
|||
|
|
- **Connected but no notifications**:
|
|||
|
|
- Confirm the CCCD write succeeds in logcat (`BLE` tag, `onDescriptorWrite CCCD status=0`).
|
|||
|
|
- Some peripherals won’t send until the CCCD is written; `setCharacteristicNotification(...)` alone is not enough.
|
|||
|
|
- **Missing service/characteristic**:
|
|||
|
|
- Verify the peripheral uses the exact UUIDs in `app/src/main/java/sh/nym/irisglass/Constants.java`.
|