4.1 KiB
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_TXby writing the CCCD (0x2902). - Reassembles chunked notifications into a UTF-8 JSON
FeedEnvelopeand logs it. - Parses JSON with
org.jsoninto 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:
BLEscan/connect/subscribeFEEDreassembly + parsingHUDLiveCard 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...](type0x01=feed,0x02=ping) - Binary V2:
[type:1][msgId:2 LE][chunkIndex:2 LE][totalChunks:2 LE][utf8-bytes...](type0x01=feed,0x02=ping) - ASCII fallback: if the payload contains a
{...}JSON object, it is parsed directly;PING/pingupdates 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:
- Install the SDK add-on: Google Inc. → Glass Development Kit Preview (API 19) in the Android SDK Manager.
- Set the module
compileSdkto the add-on inapp/build.gradle(or via Android Studio Project Structure).
Install on Glass
- Enable developer mode + ADB on Glass.
- Connect over USB and verify:
adb devices
- Install:
./gradlew :app:installDebug
- Launch “Iris Glass” on Glass.
Expected behavior:
- Within ~15 seconds (scan + connect), the LiveCard status should reach “Connected”.
- On the first full feed,
FEEDlogs 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 (
BLEtag,onDescriptorWrite CCCD status=0). - Some peripherals won’t send until the CCCD is written;
setCharacteristicNotification(...)alone is not enough.
- Confirm the CCCD write succeeds in logcat (
- Missing service/characteristic:
- Verify the peripheral uses the exact UUIDs in
app/src/main/java/sh/nym/irisglass/Constants.java.
- Verify the peripheral uses the exact UUIDs in