←  All posts

You don't need a smart-glasses SDK to build a voice app

If your app only needs a microphone and a speaker, it already runs on smart glasses — no vendor SDK, no registration, no developer-preview approval. How that works, apps already shipping it, when you genuinely do need the vendor path, and what's left for Extentos to do.

If your app only needs a microphone and a speaker, it already runs on smart glasses. No Meta Device Access Toolkit, no app registration, no developer-preview approval, no waitlist. The iOS and Android audio code you have today is enough.

That isn't a workaround. It's what the hardware actually is.

How it works

Smart glasses aren't a platform you port to. They're an accessory to the phone. Your app never runs on the glasses — it runs on the phone and reaches through, and what it reaches through is ordinary Bluetooth.

The glasses pair as a Bluetooth audio peripheral, exactly like a headset. The Hands-Free Profile carries a duplex voice channel: the wearer's microphone in, your synthesised speech out. A2DP carries higher-quality playback when you're not capturing. Both profiles have been standard since the early 2000s, and the phone's operating system owns the routing — your app asks for a voice session and the OS hands it whatever audio device is currently connected.

Which means the code is the code you already know:

  • iOS — configure an AVAudioSession with .playAndRecord, .voiceChat and .allowBluetooth, then run AVAudioEngine with SFSpeechRecognizer for transcription and AVSpeechSynthesizer for speech.
  • Android — select the Bluetooth SCO communication device through AudioManager, then move bytes with AudioRecord and AudioTrack.

Nothing in that chain is vendor-specific. Nothing in it knows the difference between glasses and AirPods, because at the audio layer there isn't one.

So the vendor SDK isn't an access gate. It's a capability gate — it exists to expose what standard Bluetooth profiles don't hand you: the camera, the display, and hardware input.

Apps are already shipping this way

This isn't theoretical. It's how you ship a hands-free voice app to the App Store today without waiting on anyone.

Meta's Device Access Toolkit is still a developer preview. Getting in means an account, a registration, and approval on Meta's timeline rather than yours — and until that clears, you can't put the app in front of users at all. Build on the audio path and none of that is in your way: no gate, no queue, no dependency on a vendor programme opening up.

Reader, a reading assistant on the App Store, is built exactly this way. It's speaker-specific rather than glasses-specific, so it works with any connected audio device, smart glasses included — and it shipped while the vendor toolkit was still preview-gated. Its developer had tried the Meta SDK and removed it, because for an audio-only app it added complexity without adding capability.

When you genuinely do need the vendor SDK

The moment your app needs to see or show something.

Photo capture, video frames, the lens display, hardware button events — that's vendor territory. It requires the SDK, the account and the registration, and there is no Bluetooth shortcut around it. If your app needs those capabilities, you need the vendor path, and anyone telling you otherwise is selling something.

So is Extentos pointless for an audio-only app?

No, and the reason is the whole point.

Getting the microphone was never the hard part. What's hard is everything after it: turn-taking that doesn't talk over the user, barge-in that stops mid-sentence the moment they interrupt, latency low enough to feel like conversation rather than a walkie-talkie, and a voice that doesn't sound like a robot. Then there's the bill, because every turn through a cloud model costs you money for exactly as long as your app is successful.

None of that is a smart-glasses problem. It's identical whether the audio arrives from AirPods, a car speakerphone, or glasses — which is precisely why it belongs one layer above the transport. That layer is what Extentos is: an agent runtime with real barge-in, tool calling, conversation state, and models that run on the user's phone so a hands-free app doesn't cost you per turn.

Bluetooth hands you a microphone. It doesn't hand you an assistant.

The exception: glasses that aren't a headset

Everything above assumes the glasses pair as a Bluetooth audio peripheral. That covers AirPods, ordinary earbuds, Ray-Ban Meta — most of what your users already own. It does not cover everything.

A category of purpose-built glasses streams microphone audio over its own BLE link instead. Brilliant Halo does this; Even Realities does too. They pair, but they never become the phone's microphone, because they were designed around a data protocol rather than a headset profile. Nothing changes on the phone's audio routing when you put them on.

The consequence is sharp: on those devices, the entire approach in this post is deaf. AVAudioSession and AudioManager hand you the phone's own microphone, and the wearer's voice is arriving as bytes over a GATT characteristic that the OS audio stack knows nothing about. Every "you don't need an SDK" argument stops at the device boundary.

This is worth stating plainly because it cuts against the headline. The audio path is genuinely the right starting point, and standard Bluetooth genuinely covers most hardware — but "most" is not "all", and a post that said otherwise would be wrong in a way you'd discover only after buying the wrong pair of glasses.

It's also the clearest case for a transport seam. Extentos treats captured audio as a stream the SDK owns rather than something the OS routes, so audio.transcriptions() reads from the same place whether the bytes came from the phone's microphone or off a BLE characteristic:

glasses.audio.transcriptions().collect { transcript -> /* identical either way */ }

For BLE-native glasses that also means transcription can't lean on the system recogniser listening to a microphone that was never opened, so the SDK carries an on-device recogniser fed directly from the stream. Your code doesn't branch on any of this, which is the point: the audio path stays one path, and it widens to cover the devices standard Bluetooth leaves out.

And adding a camera later stays cheap

This is the part that made it worth building properly rather than just writing a blog post about.

Extentos ships a SystemAudioTransport on both platforms — the full agent runtime over the phone's own Bluetooth routing, no vendor SDK involved. On Android we also moved Meta out of the core artifact: com.extentos:glasses resolves zero DAT entries, and the vendor lives in an optional com.extentos:glasses-meta. A voice app needs no vendor credentials and no credentialed repository just to compile.

Because the agent sits above the transport, adding a camera later swaps what's underneath and leaves your conversation logic untouched. On Android that's one Gradle line: :glasses-meta self-registers at startup and transport resolution behaves exactly as before. You don't rebuild the voice side to gain a camera.

That property isn't a promise we're making. It falls out of the architecture, which is the only kind of promise worth anything.

Where to start

Building something hands-free and voice-first? Start on the audio path. It works today, on hardware your users already own, across every vendor that speaks Bluetooth audio — and through Extentos, across the supported glasses that stream their microphone over BLE instead. Our choose-your-path guide walks the decision, and the tooling derives it from the capabilities your app declares rather than asking you to guess up front.

Thanks to Reader's developer for the conversation that prompted us to formalise this path.

Asger Mølgaard
Founder