Skip to Content
Android SDKConceptsCapture lifecycle

Capture lifecycle

A capture session is a small state machine you observe through Kotlin flows. Understanding the states makes the UI wiring obvious.

The reader state machine

session.state: StateFlow<ReaderState> drives an exhaustive when:

Ready ──capture starts──▶ Scanning(position) ──frame──▶ Captured(position) ▲ │ │ hardware/transport failure └──────────────────────── Error(error)
  • Ready — reader idle, no capture in progress.
  • Scanning(position) — a capture for position (ISO 19794-4, 0..10) is running; the vendor SDK is polling for a quality frame.
  • Captured(position) — a quality-gated image was captured.
  • Error(error) — a hardware/transport failure. A biometric non-match (match / search returning matched = false) is a result, not an Error.

The three flows

FlowTypeCarries
stateStateFlow<ReaderState>Latest lifecycle state — render your capture UI from this
resultSharedFlow<ReaderCaptureResult>Emitted by capture() — the raw image (base64 PNG + byte count)
errorsSharedFlow<SladeIDError>Every handled failure (auth, capture, network)

Collect them from a coroutine scope tied to your UI (e.g. viewModelScope):

viewModelScope.launch { session.state.collect { render(it) } } viewModelScope.launch { session.errors.collect { toast(it.message) } }

Suspend, off the main thread

Capture, scoring, and submission are suspend functions dispatched to background threads by the SDK — heavy work never runs on the caller’s thread. Call them from a coroutine; they return null on a handled failure (the typed error is emitted on errors) rather than throwing across the API boundary. The only exceptions thrown are programming errors, e.g. an out-of-range position.

One capture at a time

A session serializes captures with an internal mutex, so concurrent calls queue rather than racing the hardware. Create one session per reader and reuse it.

Used in