Android SDK lifecycle
When to create and shut down ExtentosGlasses, how the bundled foreground service keeps the glasses mic alive in the background, and how Extentos behaves across Activity lifecycle and process death.
ExtentosGlasses is a long-lived object with an explicit start and stop. You own its lifetime — it doesn't auto-register with the Android lifecycle, so where you create and release it is your decision.
Create once, shut down once
// Start: hold the handle for the life of the glasses session.
val glasses = ExtentosGlasses.create(config)
// Stop: release the transport and cancel the SDK's coroutine scope.
suspend fun tearDown() {
glasses.shutdown()
}shutdown() is a suspend function — call it from a coroutine. It shuts down the active transport (closing the DAT/Bluetooth or WebSocket connection) and cancels the internal SupervisorJob scope that drives every Flow the SDK emits. After shutdown(), the instance is spent; create a new one if you need to reconnect.
Where to anchor it:
-
App-scoped session (the common case — glasses connection persists across screens): create it in a holder tied to your application or a shared
ViewModel, and callshutdown()when the user explicitly disconnects or the app is being torn down. -
Screen-scoped session: create it in a screen-level
ViewModeland callshutdown()fromonCleared(). The rule is one live instance at a time, not one per process — this is safe only if exactly one screen owns it and the old one is shut down before the next is created. If two screens can be alive at once, use the app-scoped holder instead; two concurrent instances each run their own auto-bind probe and telemetry registration and will fight over the transport.class GlassesViewModel : ViewModel() { val glasses = ExtentosGlasses.create(config) override fun onCleared() { viewModelScope.launch { glasses.shutdown() } } }
Don't create a fresh ExtentosGlasses per Activity.onCreate if the same glasses session should outlive configuration changes — a ViewModel survives rotation; the Activity does not.
Activity and Fragment wiring
The SDK needs an Activity in two situations, both supplied through ExtentosConfig:
applicationContext— required when the transport resolves to RealMeta (Meta DAT initializes against aContext). PassapplicationContext, not an Activity, so the reference is safe to hold.activityProvider: () -> Activity?— Meta registration (the pairing handoff) needs a foreground Activity. Provide a closure that returns your current top Activity (e.g. from anActivityLifecycleCallbacks-tracked reference), so the SDK can launch registration when the user connects.
ExtentosConfig(
applicationContext = applicationContext,
activityProvider = { topActivityRef.get() }, // your current foreground Activity
)Observe connection state from your UI through connection.state (a StateFlow<GlassesState>) — collect it lifecycle-aware with repeatOnLifecycle so you stop collecting when the screen is stopped. See Threading.
Background capture and the foreground service
Capability subscriptions (glasses.audio.*, the assistant) run on the SDK's coroutine scope, which is bound to your process — not to any Activity. While your app is foreground, that's enough. To keep the glasses mic alive while your app is backgrounded (a voice assistant or live transcription that must keep listening), start the library's bundled foreground service:
import com.extentos.glasses.core.service.GlassesForegroundService
// AFTER RECORD_AUDIO is granted at runtime — typically in the grant callback:
GlassesForegroundService.start(this)
// When background capture is no longer needed:
GlassesForegroundService.stop(this)The service is declared for you in the library manifest (foregroundServiceType="microphone"), so you only start/stop it — see Manifest setup. Key rules:
- Permission first.
RECORD_AUDIOmust already be granted. On Android 14+, starting the service without the grant throwsSecurityExceptionat service-create time and kills the app before the first frame draws. - Not from
Application.onCreate. The grant can't exist that early. Start it from an Activity (or aViewModelscoped to one) inside the permission-grant callback, or after acheckSelfPermission(...) == PERMISSION_GRANTEDcheck. - Idempotent. Calling
startagain while running just updates the notification. - Camera-only or strictly foreground apps don't need it.
Process death
Extentos holds no implicit cross-process state to restore: an ExtentosGlasses instance and its transport connection do not survive the process being killed. After process death and relaunch, you re-run ExtentosGlasses.create(...) and reconnect — exactly as on first launch. The dev-loop pairing identity is persisted to filesDir, so an Auto-resolved dev session can re-bind without re-pairing, but the live glasses connection itself is re-established from scratch.
Because operations return ExtentosResult rather than throwing, a connection lost across a lifecycle gap surfaces as a typed failure on the next call — CaptureError/AudioError.NotConnected from a capability call, or a ConnectError (NoDeviceAvailable / TransportFailure) from connect()/reconnect() — pattern-match and re-establish rather than guarding with try/catch.
Related
Initialize the Android SDK
Create ExtentosGlasses with ExtentosGlasses.create, configure ExtentosConfig (environment, applicationContext, transport), reach the sub-clients, and pattern-match ExtentosResult.
Android manifest setup
Which permissions the Extentos Android SDK auto-merges for you and which capability permissions (CAMERA, RECORD_AUDIO, INTERNET) your app must declare, plus the bundled foreground service.
Android SDK threading model
How the Extentos Android SDK uses Kotlin coroutines and Flow — suspend functions for one-shot ops, Flow/StateFlow for streams, and which dispatcher to collect on.
Error reference
Every typed error the Extentos SDK can return — ConnectError, CaptureError, AudioError, TransportError, the ExtentosError umbrella, and the Meta-DAT DeviceSessionError — with their payload fields and meaning. Lifecycle operations return ExtentosResult<T, E> with these concrete failure variants rather than throwing; pattern-match them. Generated from the Rust core.
Initialize the Android SDK
Create ExtentosGlasses with ExtentosGlasses.create, configure ExtentosConfig (environment, applicationContext, transport), reach the sub-clients, and pattern-match ExtentosResult.
Android SDK threading model
How the Extentos Android SDK uses Kotlin coroutines and Flow — suspend functions for one-shot ops, Flow/StateFlow for streams, and which dispatcher to collect on.