← Back

Alignment of Glasses Speech Interfaces

How Apple, Android, Meta and Snap each expect a head-worn app to listen — the interaction timelines, the platform constraints, and the certification clauses that decide whether it ships.

Perishable report Compiled 2026-09-25

Head-mounted speech guidance is thinner than mobile speech guidance on every one of these four platforms. Where a vendor publishes no HMD-specific rule, this report falls back to the comparable phone OS and says so in the cell. Claims carry one of two markers: doc means a named vendor page states it, est. means it is inferred from the mobile equivalent, from a deprecation notice, or from developer reports rather than from a published requirement.

Refresh this report whenever any of these land: a visionOS or iOS major release, an Android XR platform release or Google Play policy change, a Meta Connect announcement or a Wearables Device Access Toolkit move out of beta, a Snap OS release or the 2026 Specs consumer launch, or any revision of the App Review Guidelines, Play Developer Program Policy, Horizon VRC list or Snap submission guidelines. Every est. cell is a candidate to be replaced with a citation, or corrected. The basis tag on each column says which of those triggers is nearest.

doc stated in vendor documentation est. inferred — hover the tag for how it was derived
Column basis — how much churn to expect: documented · stable published, shipping, unlikely to move documented · thin shipping, but silent on the headset, so cells rest on the mobile fallback part beta mature core, pre-release edges high churn APIs or hardware changing right now

Part 1

Interaction timelines

Two sequences per platform: a discrete command the user fires once, and a continuous listening state the user switches on. Each diagram splits the User, the Hardware/OS, and the App/Engine so you can see exactly which layer owns the microphone indicator and which layer ends the session.


Each tab has one horizontal scrollbar shared by both of its diagrams, so they move together — they are drawn at full width rather than squeezed to fit. Solid arrows into the “what the user sees” lane are changes to the display; dashed arrows back to the User are what they hear. Both lanes are written as the user would describe them rather than as widgets to build. Read the Note bands as constraints rather than steps — they mark the point where the platform, not the app, decides what happens. The recurring pattern across all four: the app owns activation and feedback, the OS owns the indicator, and nobody lets a third-party app own the wake word.

Scope: the app stays in front of the user. Every timeline below runs with the app in the foreground and the user attending to it. Sending it behind something else changes continuous speech on all four platforms — capture can be cut mid-sentence, the session has to be resumed rather than restarted, and a partial transcript has to survive the gap. That recovery is real work and it is not drawn here. The background rules themselves are in Table B.

The state model both channels carry

Every state below changes something the user can see and something the user can hear. Both columns are written as the user would describe them, not as components to build — a meter that tracks amplitude is one way to do the listening row, but what the row actually asks for is that the person can tell the app is live rather than frozen. No platform requires both channels, and no two platforms name the same one, so designing to the mandate alone produces an app that feels different on each device. Design the pair, then drop whichever channel a given device cannot carry.

StateWhat the user seesWhat the user hears
idleNothing new. The app looks the way it did before they thought about speaking.Nothing.
armedWhatever they just acted on changes, and the app names what it is listening for.A short tone as the microphone opens.
listeningSomething responds to the room, so they can tell the app is live rather than frozen or crashed.Nothing. The quiet is what tells them it is their turn.
hearingTheir own words appear as they say them, and look unfinished, so they know the app may still change its mind.Nothing. The app does not speak over the person speaking to it.
interpretingThe words stop changing and settle. The app shows that it is working on them.A short tone as the microphone closes, so they know they can stop talking.
confirmedThe thing the words acted on is pointed out before it changes, so they can see what moved and what did not.The app says back what it did, in one short sentence.
mutedThe app says it is not listening, and says who stopped it — them, or the system.The same closing tone as before. Never the sound that means it worked.
failedThe app says what went wrong in plain words, with the way to try again next to it.A sound clearly unlike the successful one, and the reason spoken aloud if the user has no display to read.

Two of these are easy to skip and cost the most when they are missing. listening has to look different from idle even though nothing has been said yet — otherwise the user cannot tell a live app from a hung one, and starts repeating themselves. muted has to be unmistakable from confirmed even though both end with the microphone closed — otherwise they walk away believing something happened.

Which channel each vendor actually mandates

PlatformThe channel the vendor namesWhat that leaves you
AppleEither. 2.5.14 asks for “a clear visual and/or audible indication when recording”.docBoth are individually optional, so review pressure alone will not make you build the pair. The OS indicator satisfies nothing on its own — it reports capture, not app state.
AndroidVisual, and the OS draws it for you: the mic indicator plus the foreground-service notification.docNo audible requirement at all. Every earcon is yours, which means nothing stops the app shipping silent — and a glanceable device is exactly where silence hurts.
MetaAudible. “Ensure transparent activation” through earcons or conversational cues.docThe visual state is entirely your design. On Ray-Ban Meta there is no display, so the audible channel is the only one there is.
SnapVisual. Published lenses must “display visuals indicating required actions upon activation”.docAudio playback during mic capture is prohibited, so the audible channel is structurally unavailable until the mic closes. Every state change up to interpreting has to be carried visually.doc
The trap. Meta names the audible cue, Snap forbids it while the mic is open, Android mandates neither, and Apple accepts one or the other. Build the pair once as a state machine, then let each platform suppress the channel it cannot carry — rather than designing four different feedback models and discovering at review that three of them are silent.

visionOS 26 inherits the iOS Speech framework wholesale. SpeechAnalyzer and SpeechTranscriber ship on iOS, iPadOS, macOS, visionOS and tvOS 26 and run on-device; SFSpeechRecognizer remains the legacy path. There is no visionOS-only speech API, so the mobile rules are the rules.

A · Discrete speech command — pinch-and-hold to talk

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant A as App · SwiftUI/RealityKit
    participant OS as visionOS · Speech + AVFAudio
    participant I as App Intents
    U->>A: Pinch and hold the Ask control
    A->>OS: AVAudioSession playAndRecord with duckOthers, then requestRecordPermission
    A->>UI: idle to armed, the control changes and names what it is listening for
    A-->>U: A short tone as the mic opens
    OS-->>U: System mic indicator lights, app cannot suppress it
    A->>OS: SpeechTranscriber attached to a SpeechAnalyzer input sequence
    A->>UI: armed to listening, something moves with the room so it reads as live
    OS-->>A: Volatile results, on-device, no network egress
    A->>UI: listening to hearing, their words appear as they say them, still unsettled
    U->>A: Release the pinch
    A->>OS: analyzer.finalizeAndFinish
    A->>UI: hearing to interpreting, the words stop changing and settle
    A-->>U: A short tone as the mic closes, so they know to stop talking
    A->>I: Resolve to an AppIntent and perform it
    I-->>A: Intent result
    A->>UI: interpreting to confirmed, the thing that changed is pointed out first
    A-->>U: The app says back what it did, in one short sentence
    A->>OS: setActive false, notifyOthersOnDeactivation
    OS-->>U: Indicator clears, ducked audio restores
    A->>UI: confirmed to idle, the control returns to how it started
    Note over A,OS: 2.5.14 accepts a visual and or audible indication,
so either channel alone passes review. Pairing them
is a design decision, not a compliance one

B · User-enabled continuous speech — live dictation toggle

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant A as App
    participant OS as visionOS · Speech + AVFAudio
    U->>A: Turn Live dictation on
    A-->>U: Consent sheet naming what is captured and where it goes
    A->>OS: AVAudioSession playAndRecord plus duckOthers
    A->>UI: idle to armed, a place for the words opens and stays open
    A-->>U: A short tone as the mic opens, once for the session, not once a sentence
    OS-->>U: Mic indicator stays lit until they turn it off
    OS-->>A: Other media ducks
    A->>UI: armed to listening, something moves with the room so it reads as live
    loop While it is on and the app is in front of them
        OS-->>A: Volatile results, low latency, may still change
        A->>UI: listening to hearing, their words appear as they say them
        A-->>U: Nothing. The app does not speak over them
        OS-->>A: Finalized result at the sentence boundary
        A->>UI: hearing to listening, the sentence settles and stops changing
        A-->>U: A quiet tick as the sentence settles, switchable off
    end
    U->>A: Turn it off, reachable in one action at any time
    A->>OS: finalizeAndFinish then setActive false
    A->>UI: listening to idle, the words area closes
    A-->>U: A short tone as the mic closes
    OS-->>U: Indicator clears

Android XR publishes a real glasses ASR guide — SpeechRecognizer.createOnDeviceSpeechRecognizer() inside the projected activity — but it is silent on timeouts, indicators and ducking, so those rows fall back to Android mobile, where they are strictly specified.

A · Discrete speech command — touchpad hold or system wake word

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant HW as Glasses · touchpad and mics
    participant A as App activity
    participant OS as Android XR
    participant G as Gemini
    U->>HW: Touch and hold the touchpad, or speak the system wake word
    HW->>OS: Assistant activation
    OS-->>U: System mic privacy indicator in the status area
    alt App-scoped recognition
        A->>OS: checkSelfPermission RECORD_AUDIO
        A->>OS: createOnDeviceSpeechRecognizer in onCreate, then startListening
        A->>UI: idle to armed, a small area opens and names what it wants to hear
        A-->>U: A short tone as the mic opens
        OS-->>A: onReadyForSpeech then onBeginningOfSpeech
        OS-->>A: onPartialResults
        A->>UI: armed to hearing, their words appear as they say them
        OS-->>A: onResults with RESULTS_RECOGNITION and CONFIDENCE_SCORES
        A->>UI: hearing to interpreting, the words settle and the app shows it is working
        OS-->>A: onEndOfSpeech, the recognizer stops itself
    else System-routed to the assistant
        OS->>G: Utterance
        G->>A: Function call into your declared app actions
        A->>UI: idle to interpreting, the app shows what it was asked to do
    end
    A->>UI: interpreting to confirmed, the thing that changed is pointed out first
    A-->>U: The app says back what it did, in one short sentence
    A->>UI: confirmed to idle, the area closes
    Note over OS,A: One shot only. A single startListening ends at
onEndOfSpeech. Continuity is the app restarting it Note over U,UI: Android mandates the visual channel at OS level and
mandates no audible one at all, so everything the user
hears here is yours to design and to keep consistent

B · User-enabled continuous speech — live captions or dictation

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant A as App
    participant OS as Android XR
    U->>A: Turn on continuous dictation
    A->>OS: Request RECORD_AUDIO if not already held
    OS-->>U: System mic indicator appears and stays up
    A->>UI: idle to listening, a place for the words opens and stays open
    A-->>U: A short tone as the mic opens, once for the session
    loop While it is on and the app is in front of them
        OS-->>A: onPartialResults
        A->>UI: listening to hearing, their words appear as they say them
        OS-->>A: onEndOfSpeech after silence
        A->>UI: hearing to listening, the line settles and stops changing
        A->>OS: startListening again to keep the session alive
        Note over A,UI: The restart has to be invisible. The user never sees
a gap between one sentence and the next end U->>OS: May mute from the system mic control at any time OS-->>A: onError, capture stops A->>UI: any state to muted, the app says it stopped and says who stopped it A-->>U: A tone that is clearly not the one that means success U->>A: Turn it off A->>OS: stopListening then destroy A->>UI: muted or listening to idle, the words area closes A-->>U: A short tone as the mic closes Note over A,OS: Foreground only. Carrying this session on with the app
behind something else needs a microphone foreground
service and its own recovery path, not drawn here

Meta is the only vendor that publishes hard numeric listening limits: Voice SDK stops after two seconds of silence or twenty seconds total. Ray-Ban Meta is a different world again — the Wearables Device Access Toolkit gives you HFP or beta in-stream PCM, and nothing else.

A · Discrete speech command — app-supplied activation into Wit.ai

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant A as App · Meta XR Voice SDK
    participant OS as Meta Horizon OS
    participant W as Wit.ai NLU
    Note over U,A: No third-party wake word exists. The app must
design its own activation event as the wakeup call U->>A: Press the control, or make the hand gesture the app defines A->>OS: RECORD_AUDIO consent, prompted at app launch OS-->>U: System microphone state reflects capture A->>A: AppVoiceExperience.Activate A->>UI: idle to armed, the control changes and names what it wants to hear A-->>U: A short tone as the mic opens, the cue Meta names explicitly Note over A: Listening begins once audio passes a volume threshold A->>UI: armed to listening, something moves with the room so it reads as live A->>W: Stream captured audio for transcription and NLU W-->>A: Partial transcript A->>UI: listening to hearing, their words appear as they say them W-->>A: Final transcript, intent and entities A->>A: Conduit binds the intent to a method A->>UI: hearing to interpreting, the words settle beside the option they matched A-->>U: A short tone as the mic closes, then the app says back what it understood U->>A: Confirm, or correct it before anything happens A->>UI: interpreting to confirmed, the thing that changed is pointed out first A-->>U: The app says what it did, in one short sentence A->>UI: confirmed to idle, the control returns to how it started Note over A: Recording auto-stops after 2 s of silence or 20 s of
total capture, whichever comes first Note over U,UI: Meta names the audible channel and leaves everything the
user sees to the app. Snap requires visuals on activation and
bars audio during capture, so one shared design must carry
both channels and let each platform drop the one it cannot

B · User-enabled continuous speech — held-open mic, with the Ray-Ban fallback

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant A as App · Voice SDK
    participant OS as Horizon OS
    participant W as Wit.ai
    participant RB as Ray-Ban Meta path
    U->>A: Turn on continuous listening in app settings
    A-->>U: Explain the capture, offer a mute that is always one action away
    A->>OS: Hold the mic open while the app is in front of them
    A->>UI: idle to listening, a standing sign that the app is listening
    A-->>U: A short tone as the mic opens, once for the session
    loop While it is on and the app is in front of them
        A->>W: Stream audio
        W-->>A: Partial then final transcripts
        A->>UI: listening to hearing, their words appear as they say them
        A->>A: Re-activate before the 20 s cap expires
        A->>UI: hearing to listening, the sentence settles
        A-->>U: Nothing at the seam. No tone, no gap
    end
    Note over A,OS: The 20 s cap is per activation, so a continuous session is
the app stitching activations together. The user must not
be able to see or hear the seam U->>A: Mute A->>A: Deactivate, release the mic A->>UI: listening to muted, the sign says it is not listening and who stopped it A-->>U: A short tone as the mic closes Note over RB: Ray-Ban Meta has no display, so there is nothing for the
user to see and everything has to be heard. The toolkit
gives HFP with beamformed voice or beta in-stream PCM at
16, 44.1 or 48 kHz. No raw mic streams, no custom wake
words, no access to the Hey Meta hot-word detector

Snap split its stack: VoiceMLModule still serves Snapchat lenses, but it is no longer supported on Spectacles, which use AsrModule instead. The two have different language coverage, different callbacks and different failure modes, so a lens that targets both needs two code paths.

A · Discrete speech command — AsrModule on Spectacles

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant L as Lens · Lens Studio
    participant OS as Snap OS
    participant C as Snap speech service
    Note over L,OS: Mic permission is declared automatically by using
AsrModule, VoiceMLModule or DialogModule U->>L: Look at the thing and speak, or press to talk L->>OS: require LensStudio AsrModule OS-->>U: Snap OS reflects that the mic is capturing L->>UI: idle to armed, the lens names what it is listening for L->>OS: startTranscribing with mode HighSpeed and silenceUntilTerminationMs L->>UI: armed to listening, something moves so it reads as live, not frozen OS->>C: Audio C-->>L: onTranscriptionUpdateEvent, isFinal false L->>UI: listening to hearing, their words appear as they say them C-->>L: onTranscriptionUpdateEvent, isFinal true after the silence window L->>UI: hearing to interpreting, the words settle and stop changing L->>L: Match the transcript to a lens action L->>OS: stopTranscribing L->>UI: interpreting to confirmed, the thing they spoke to reacts visibly L-->>U: A short tone, the first sound the lens is allowed to make L->>UI: confirmed to idle, the prompt clears Note over C: Error codes include NoInternet and Unauthenticated, so
being offline has to be something the user can see Note over U,UI: Snap requires visuals naming the required actions on
activation and forbids audio playback during capture, so
nothing can be heard until the mic closes

B · User-enabled continuous speech — rolling transcription

sequenceDiagram
    autonumber
    actor U as User
    participant UI as What the user sees
    participant L as Lens
    participant OS as Snap OS
    participant C as Snap speech service
    U->>L: Turn on continuous transcription in the lens
    L->>UI: idle to listening, a standing sign that the lens is listening
    L->>OS: startTranscribing with mode HighAccuracy
    loop While it is on and the lens is running
        C-->>L: Rolling partial transcript
        L->>UI: listening to hearing, their words appear as they say them
        Note over C,L: silenceUntilTerminationMs marks a fragment final
        L->>UI: hearing to listening, the fragment settles and stops changing
    end
    Note over L,UI: Audio playback during mic capture is prohibited, so for the
whole session there is nothing to hear. Every state change
has to be carried by what the user can see U->>L: Turn it off L->>OS: stopTranscribing L->>UI: listening to idle, the words area clears L-->>U: A short tone as the mic closes, now that it is allowed Note over L,OS: A published lens may not combine sensitive user data with
external connectivity. Remote Service Gateway is the
documented exception

Part 2 · Table A

Architecture and UI patterns

What you build with, and what the platform expects the user to see while you are listening.


ConceptApple · visionOSdocumented · stableReview rules are long settled. The speech API is one release old, and visionOS adds none of its own.Android XRdocumented · thinPlatform is shipping, but the XR speech pages say nothing about indicators, timeouts or ducking — those cells rest on the mobile fallback.Meta · Horizon OSpart betaQuest Voice SDK is mature. The Ray-Ban Wearables toolkit is beta, and its in-stream audio capture is development and beta channels only.Snap · Snap OShigh churnVoiceML is already retired on Spectacles in favour of AsrModule, and consumer Specs arrive on Snap OS 2.0.
Primary native APIs SpeechAnalyzer + SpeechTranscriber in the Speech framework, on iOS, iPadOS, macOS, visionOS and tvOS 26, running on-device. SFSpeechRecognizer is the legacy path. Intent routing through App Intents.doc SpeechRecognizer.createOnDeviceSpeechRecognizer() with RecognitionListener and RecognizerIntent, instantiated in the projected activity's onCreate(). Gemini Live API with function calling for app-wide voice navigation. ML Kit GenAI speech recognition where a Gemini Nano class model is present.doc Meta XR Voice SDK, backed by the Wit.ai NLU service, for Unity and Unreal. AppVoiceExperience.Activate() to start capture; Conduit binds a resolved intent to a method. Ray-Ban Meta uses the separate Wearables Device Access Toolkit.doc AsrModule on Spectacles — require('LensStudio:AsrModule'), startTranscribing() / stopTranscribing(), 40+ languages, Lens Studio 5.9.0+ and Snap OS 5.61+. VoiceMLModule for Snapchat lenses only; its capabilities are no longer supported on Spectacles.doc
Wake word architecture System-level only. “Siri” is the wake word and it belongs to the OS; a third-party app cannot register its own. Apps reach the assistant by adopting App Intents, and 2.5.11 restricts you to intents your app can actually fulfil.doc A custom in-app hot word would need your own always-on recognizer, which the recording rules make hostile.est. System-level. The touchpad hold and the system wake word both route to Gemini. No documented API for a third-party wake word, so a custom hot word means running your own detector inside a microphone foreground service with its persistent notification.est. Explicitly unavailable. Meta's own Voice SDK tutorial tells you to design an activation event as the app's wakeup call.doc That “Hey Meta” is an always-on hardware detector Meta has not opened to third-party SDKs, and that the hardware takes no custom wake word, comes from a developer thread on Meta's toolkit repo rather than from a published rule.est. No third-party wake word. Snap ships a fixed voice-command vocabulary for capture — “Take a Snap”, “Start Recording”, “Stop Recording” — and lens-level navigation intents through the VOICE_ENABLED_UI model. A lens starts listening when the lens decides to.doc
Activation methods Pinch or tap on a visible affordance; gaze-plus-pinch on a control; Siri; Voice Control for gesture-equivalent commands; dictation from any text field, with dictation, spelling and command modes.doc Touch-and-hold on the glasses touchpad launches Gemini; system wake word; in-app button or gesture; physical buttons for camera and display. Hands, eyes, voice, keyboard, mouse, trackpad and 6DoF controllers are all first-class inputs.doc App-supplied only: a UI button, a controller press, a hand gesture, or any event the app defines. Voice SDK begins recording once captured audio passes a volume threshold after activation.doc Lens-initiated startTranscribing() or startListening(); hand tracking and voice are the two Snap OS input modes. Press-to-talk is an app-level pattern, not something the platform provides.est.
App speech customization contextualStrings on SFSpeechRecognitionRequest — a phrase list the recognizer is biased toward. No grammar, no custom model training.doc In the iOS 26 Speech framework the lever moved and did not fully survive: DictationTranscriber takes AnalysisContext.contextualStrings, but the long-form SpeechTranscriber does not, so on the new API you can have biasing or long-form transcription, not both.est. EXTRA_BIASING_STRINGS — “Optional list of strings, towards which the recognizer should bias the recognition results.” Alongside it, EXTRA_ENABLE_BIASING_DEVICE_CONTEXT biases toward what is already on the device, and is documented to “have no effect” depending on the recognizer implementation.doc No grammar. Whether the hint list is honoured is the recognizer’s choice too, so the same strings can work on one device and do nothing on the next.est. Keywords, synonyms and trained intents. Dynamic entities ship keywords and synonyms with each individual request and “bias the model towards values that the system knows are acceptable values”; Meta names an end user’s contact list as the example. Underneath that you train intents and entities in the Wit.ai app and can hand-add synonyms.doc Snapchat lenses and Spectacles behave differently. Snapchat lenses bias the transcription — options.addSpeechContext(phrases, boost), boost 1–10, documented for “words which are rarer and aren’t picked up well enough”. Keyword groups (addKeywordGroup) only match against the transcript afterwards, so they never improve it. Spectacles get nothing: AsrTranscriptionOptions carries four properties — mode, silence timeout and two callbacks — and no vocabulary, hint or grammar of any kind.doc
Uncommon people names Load the names before you ask. contextualStrings takes the roster you expect, and SiriKit adds INVocabulary for user-specific terms including contact names, registered as an ordered set with the most-used first.doc A name you did not supply comes back as the nearest ordinary word, and nothing in the result says a substitution happened.est. Supply the names as hint strings, and switch on device-context biasing, which is the nearest thing Android offers to “use the contacts on this device”.doc Because a recognizer may honour either, both or neither, the same name can resolve on one headset and fail on the next with nothing in the result to distinguish the two cases. CONFIDENCE_SCORES is the only signal you can gate on.est. Dynamic entities are supplied per request rather than fixed at build time, so push the roster that applies at that moment — the people in this call, this match, this room — and the model biases to it for that utterance.doc A name outside the pushed set falls back to the general model and is transcribed as something ordinary.est. Accented, apostrophed and hyphenated names cannot be boosted at all: Snap requires that boosted phrases “should be made of lowercase a-z letters”, so the names most likely to be mis-transcribed are the ones the API will not accept. O’Brien, Nguyễn and Müller are unreachable.doc On Spectacles there is no lever at all, so an uncommon name is whatever the 40+ language model decides it heard.doc
Required app UI feedback Guideline 2.5.14 requires “a clear visual and/or audible indication when recording” — this is a review requirement, not a suggestion, and it sits on top of the OS indicator. Practically: a lit listening state, streaming volatile results, and a distinct finalized state.doc Design guidance for glasses asks for glanceable, contextual, minimally intrusive surfaces and subtitles for people who are deaf or hard of hearing. Live partial transcription is the natural fit; there is no specific waveform mandate.doc Read the mandate as the mobile prominent-disclosure rule plus the foreground-service notification.est. “Ensure transparent activation” — give clear mic activation awareness through earcons or conversational cues, and confirm the user's input and the system's understanding of the selected option before acting.doc Lenses published to Lens Explorer must “display visuals indicating required actions upon activation” and run at 60 fps — so a voice lens has to show that it is listening and what it expects you to say.doc
Multimodal fallback 5.1.1 (iv): respect the permission setting and “where possible, provide alternative solutions for users who don't grant consent.” A voice-only flow with no keyboard or pinch equivalent fails this directly.doc “Give users control” — let users tailor the experience and remap controller buttons and gestures to fit their physical needs. Voice is one modality among many rather than the entry point.doc Multimodal interaction is a stated design principle: let users switch modality mid-interaction, for example from voice to text, and provide alternative input methods when an interaction errors.doc Not stated as a requirement. Snap OS itself is hand-tracking plus voice, so hand input is the de facto fallback and a voice-only lens is a review risk rather than a documented rejection.est.
What the last two rows add up to. Not one of the four platforms guarantees an uncommon name, and two of them can drop your hint list without saying so. Treat a rare name as something the user picks or confirms, never as something they must say and be understood the first time — and push the names you know about with every request on the platforms that let you.

Part 2 · Table B

Certification and OS constraints

What the platform does to you whether you want it or not, and the clauses that get an app sent back.


ConstraintApple · visionOSdocumented · stableReview rules are long settled. The speech API is one release old, and visionOS adds none of its own.Android XRdocumented · thinPlatform is shipping, but the XR speech pages say nothing about indicators, timeouts or ducking — those cells rest on the mobile fallback.Meta · Horizon OSpart betaQuest Voice SDK is mature. The Ray-Ban Wearables toolkit is beta, and its in-stream audio capture is development and beta channels only.Snap · Snap OShigh churnVoiceML is already retired on Spectacles in favour of AsrModule, and consumer Specs arrive on Snap OS 2.0.
Mandatory privacy indicators The OS draws a microphone indicator whenever an app uses the mic — visible in the app, in another app, or at the Home Screen — and the app cannot suppress it.doc visionOS inherits this behaviour; Apple documents the indicator for iOS and iPadOS rather than for visionOS specifically.est. The system microphone indicator and the global mic toggle are platform behaviour on Android 12 and later, and a microphone foreground service additionally shows a persistent notification.doc Android XR docs do not restate the indicator for glasses.est. The Horizon OS permission dialog appears at app launch and microphone appears in the app's listed permissions.doc Meta's voice design guidance asks for app-drawn awareness through earcons rather than promising an OS chrome indicator, so budget for your own.est. Snap documents that the microphone captures voice data for recorded videos and voice commands and that camera and mic access are essential to the device functioning, but does not specify a capture indicator for lens-initiated ASR.est.
Continuous listening limits No published time cap on the API. The practical limit is foreground lifetime: without an audio background mode, capture stops when the app is no longer foreground, and background capture reads as surreptitious recording under 2.5.14.est. A single startListening() is one utterance and ends at onEndOfSpeech; continuity is your loop.doc Background capture requires a microphone foreground service, which cannot be started from the background or from a BOOT_COMPLETED receiver, and RECORD_AUDIO is while-in-use restricted.doc Voice SDK publishes explicit numeric limits: recording stops after 2 seconds of silence or 20 seconds of total recording, whichever comes first, so a continuous session is stitched activations.doc silenceUntilTerminationMs finalizes a fragment after a configured silence window rather than ending the session; you choose the value.doc VoiceML notes that muting the mic for more than two minutes requires a preview reset.doc No documented session cap on Spectacles.est.
Audio session conflicts AVAudioSession arbitrates: playAndRecord to capture while playing, with duckOthers or mixWithOthers to decide what happens to other media, and notifyOthersOnDeactivation to hand playback back cleanly.doc Standard Android audio focus and stream routing; on Ray-Ban-style audio glasses the system routes to the wearable's mics. No XR-specific ducking contract is published.est. On Quest the app manages its own mic and playback. On Ray-Ban Meta, HFP mode beamforms the wearer's voice and narrows the return audio path, while beta in-stream capture delivers uncompressed PCM at 16, 44.1 or 48 kHz alongside video without dropping A2DP output quality.doc Hard constraint: audio playback during microphone capture is prohibited. Duck or suspend the lens's own audio rather than mixing it under capture.doc
Permissions and strings NSMicrophoneUsageDescription plus NSSpeechRecognitionUsageDescription — recognition is a second prompt on top of the mic prompt. 5.1.1 (ii) requires purpose strings that “clearly and completely describe your use of the data” and an accessible way to withdraw consent.doc android.permission.RECORD_AUDIO as a runtime grant, required before instantiating SpeechRecognizer. Continuous capture adds FOREGROUND_SERVICE_MICROPHONE and a manifest foregroundServiceType="microphone". Play requires a completed Data safety form and prominent disclosure before the prompt.doc android.permission.RECORD_AUDIO is a review-required permission: “Permitted uses include VOIP or other features that need microphone access,” and you must justify the use case to app review. If the user declines, the app cannot record at all and must recover.doc No manifest to write — permissions are “declared automatically when you use components like VoiceMLModule or DialogModule.” Mic falls under Sensitive User Data, which is what triggers the connectivity restriction below.doc
Primary rejection risks 2.5.14 recording without explicit consent or a clear indication. 5.1.1 (iii) asking for the mic beyond core functionality. 5.1.1 (iv) no alternative for users who decline. 5.1.2 (i) sending speech to a third-party AI service without disclosure and explicit permission. 2.5.11 registering intents you cannot fulfil, or inserting anything between request and fulfilment.doc Missing or wrong foreground-service type on Android 14+, which is a hard build-and-policy failure. Missing prominent disclosure or an inaccurate Data safety declaration for audio. Starting mic capture from the background.doc VRC.Quest.Security.2 — request the minimum permissions required and no unsupported ones. VRC.Quest.Privacy.1–5 — the privacy policy must state what is collected, how it is used and how a user requests deletion, and the team must clear data-protection checks. An unjustified RECORD_AUDIO is the specific speech trap.doc Combining sensitive user data with external connectivity in a published lens, other than through Remote Service Gateway — this blocks the obvious “send the transcript to my own LLM” design. Plus the general bar: a defined objective, visuals on activation, 60 fps, no crashes, under 25 MB for Spectacles, reviewed in 2–3 business days.doc

Part 2 · Reading

Where the platforms actually diverge


Four things separate these platforms, and none of them is the recognition quality.

Who ends the session. Apple lets you hold the mic for as long as you hold the foreground. Android ends every utterance for you and makes you restart. Meta ends it at twenty seconds whether you like it or not. Snap ends fragments, not sessions. Build the session loop for the tightest one and the others are free.
Where the audio goes. Apple's SpeechAnalyzer is on-device. Android's on-device recognizer is on-device, and Gemini is not. Meta's Voice SDK routes to Wit.ai. Snap's AsrModule returns a NoInternet error, which tells you where it runs. Egress is the difference between one consent line and a privacy-policy clause.
What the user is told, and on which channel. Apple and Android draw the capture indicator for you and make it unsuppressible — but an indicator reports the microphone, not the app’s state, and satisfies neither user. Beyond it the vendors split: Meta names the earcon, Snap names the visual and forbids audio while the mic is open, Android names neither. The only design that survives all four carries every state on both channels and lets the platform mute the one it cannot support. See the state model.
What you are allowed to do with the transcript. This is Snap's sharpest edge — sensitive user data and external connectivity cannot be combined in a published lens, so the transcript cannot simply leave for your own backend. Apple's 5.1.2 (i) permits it with explicit disclosed permission. Meta wants the justification at review. Android wants it on the Data safety form.

Reproduce

Rebuild this report

Copy the prompt, run it against current documentation, and compare the result against this page. Anything that has moved will show up as a changed cell.


Source prompt
System Role: You are an expert XR UX researcher and platform compliance analyst. Task: Conduct comprehensive research on speech interaction UI/UX patterns and platform certification requirements across four major ecosystems: 1. Apple (visionOS / Apple Vision Pro — fallback to iOS) 2. Android (Android XR — fallback to Android Mobile) 3. Meta (Meta Horizon OS / Quest / Ray-Ban Meta) 4. Snap (Snap OS / Spectacles / Lens Studio) Where specific Head-Mounted Display (HMD) or Smart Glasses guidelines are undocumented, explicitly fall back to the published UX patterns and certification requirements of their comparable phone/mobile OS. Your final deliverable must strictly follow the structure below. Part 1: Interaction Timeline Diagrams Generate timeline diagrams (using Mermaid.js sequence diagrams) mapping the sequence of events across the User, Hardware/OS, and App/Engine layers. You must create two diagrams per platform (or consolidated diagrams clearly showing platform divergences) for the following interactions: 1. Discrete Speech Command: A tap-to-talk, gesture-to-talk (e.g. Meta's speak gesture), or system wake-word trigger for a single intent. Show activation, OS-level privacy indicator triggers, audio capture, intent routing (e.g. App Intents, Wit.ai Conduit), and UI feedback. 2. User-Enabled Continuous Speech: A user toggling an "always-listening" or live dictation state in the foreground. Show continuous audio buffering, visual state indicators (e.g. waveforms, real-time transcription), background audio routing/ducking (e.g. AVAudioSession shifts), and termination limits. Part 2: Platform Comparison Tables Create comprehensive Markdown tables comparing the four platforms. The columns must be the four platforms (Apple, Android, Meta, Snap). Organize the rows by the following speech interaction concepts: Table A: Architecture & UI Patterns - Primary Native APIs (e.g. SpeechAnalyzer, Android SpeechRecognizer, Meta Voice SDK, Snap VoiceML) - Wake Word Architecture (System-level vs. Custom app-level wake word limitations) - Activation Methods (Voice, Gesture, Button, Controller) - Required App UI Feedback (Waveforms, live transcription, tactile/audio cues) - Multimodal Fallback Requirements (Keyboard/touch alternatives) Table B: Certification & OS Constraints - Mandatory Privacy Indicators (Hardware/OS-level unsuppressible dots/banners) - Continuous Listening Limits (Timeout constraints, e.g. 60-second limits, background audio bans) - Audio Session Conflicts (How concurrent media playback is handled during mic capture) - Required Permissions & Strings (e.g. NSMicrophoneUsageDescription, RECORD_AUDIO, specific user consent prompts) - Primary App Store Rejection Risks (Specific clauses that trigger certification failure) Part 3: Official Documentation Links Provide a curated list of markdown hyperlinks to the official developer documentation, App Review Guidelines, and Human Interface Guidelines (HIG) for each platform's speech, audio, and privacy sections. Ensure the links point to the most current platform data. Mark every claim as either documented or estimated, and state the date the report was compiled.