DEV Community

Rexhino Kovaci
Rexhino Kovaci

Posted on

How I built a Bluetooth smart glasses detector (iOS + Android)

Smart glasses like Ray-Ban Meta can record video silently — no indicator light, no warning to people nearby. I wanted to know when someone near me was wearing them, so I built Nearby Lens.

## How it works

Smart glasses broadcast Bluetooth Low Energy (BLE) advertisements constantly while worn — even without pairing to any device. Each manufacturer has a registered company ID in the Bluetooth SIG assigned numbers list.

Ray-Ban Meta uses manufacturer ID 0x0D53 (Luxottica) and service UUID 0xFD5F. Snap Spectacles use 0x03C2. The app listens for these passively and scores each advertisement:

  • Manufacturer ID match → up to 65 points
  • Service UUID match → up to 70 points
  • Device name keywords → up to 65 points
  • Confidence ≥ 60% triggers an alert

## The hard parts

False positives — Sony's manufacturer ID 0x012D is shared across WH-1000XM4 headphones, LinkBuds, and SmartEyeglass. Score it too high and every Sony headphone triggers an alert. Solution: low base score (15pts) + known false positive keyword list that
penalises -50pts if the device name matches "wh-1000", "linkbuds" etc.

iOS background scanning — iOS kills unrestricted BLE scans in the background. You must pass specific service UUIDs to scanForPeripherals(withServices:). We filter to known glasses UUIDs so the scan survives suspension.

BGTaskScheduler crashesCBCentralManager can fire centralManagerDidUpdateState synchronously during init on iOS 16+, which called scheduleRefreshTask() before BGTaskScheduler registration completed. Fix: register background tasks before initialising
CBCentralManager.

Distance accuracy — free-space path loss formula /20 gives wildly optimistic distances indoors. Real-world BLE in buildings needs path loss exponent ~2.5, so we use /25 capped at 50m.

## OTA rule updates

New glasses brands launch constantly. Rather than requiring an app update, rules are fetched from a JSON file on Cloudflare Pages on every scan start. Users get new detection rules silently in the background.

## Stack

  • iOS: Swift, CoreBluetooth, BGTaskScheduler, Live Activities, WidgetKit
  • Android: Kotlin, Jetpack Compose, BLE ScanFilter, Foreground Service, Room
  • Rules: JSON on Cloudflare Pages

## Try it

Free on iOS and Android — no account, no GPS, no data leaves your device.

Happy to answer questions about the BLE detection approach.

Top comments (0)