Skip to main content
Interim hand-authored reference. This page is authored directly from the Seam Android SDK public Kotlin sources. See the reference overview for context.

Overview

SeamSDK is the single entry point for all Seam Android SDK operations. It is a class with a private constructor — obtain the instance via SeamSDK.getInstance() after calling SeamSDK.initialize().
class SeamSDK private constructor()
Thread Safety
  • All StateFlow properties (credentials, isActivated, unlockStatus) are thread-safe.
  • All suspend functions can be called from any coroutine context.
  • initialize is thread-safe and idempotent.
Offline Behavior
  • The SDK caches credentials and can work offline for unlock operations.
  • activate() requires an internet connection on first activation.
  • refresh() always requires an internet connection.
  • unlock() can work offline if credentials are already cached.

Companion Object Methods

initialize(context, clientSessionToken)

Initializes the Seam Android SDK. Call this once at app launch, typically in Application.onCreate().
suspend fun initialize(context: Context, clientSessionToken: String)
Parameters
ParameterTypeDescription
contextContextThe Android application context.
clientSessionTokenStringA valid client session token for the app user.
Throws
ErrorDescription
SeamError.AlreadyInitializedThe SDK is already initialized. Call deactivate() first to reinitialize.
SeamError.InternetConnectionRequiredNo internet connection is available.
SeamError.InvalidClientSessionTokenThe token format is invalid.
SeamError.DeactivationInProgressA deactivation is already in progress.
try {
    SeamSDK.initialize(context, "seam_cst_...")
} catch (seamError: SeamError) {
    when (seamError) {
        is SeamError.AlreadyInitialized -> {
            // handle error when SDK is already initialized
        }
        is SeamError.DeactivationInProgress -> {
            // handle error when app is being deactivated
        }
        is SeamError.InternetConnectionRequired -> {
            // handle error when internet connection is required
        }
        is SeamError.InvalidClientSessionToken -> {
            // handle error when client session token is invalid
        }
        else -> {
            // handle other errors
        }
    }
}

getInstance()

Returns the singleton instance of SeamSDK. Thread-safe; can be called from any thread.
fun getInstance(): SeamSDK
Returns: The initialized SeamSDK instance. Throws
ErrorDescription
SeamError.InitializationRequiredinitialize() has not been called yet.
val seamSDK = SeamSDK.getInstance()

StateFlow Properties

credentials

The current list of SeamCredential objects for the app user. Emits an updated list whenever credentials change.
val credentials: StateFlow<List<SeamCredential>>
The list may be empty while loading or if no credentials are available. Check each credential’s errors property to determine if it is ready for use. Latest value is always available via .value.
// Observe credential changes
lifecycleScope.launch {
    seamSDK.credentials.collect { credentials ->
        if (credentials.isEmpty()) {
            // handle no credentials
        } else {
            // display credentials
        }
    }
}

// Handle credential errors
lifecycleScope.launch {
    SeamSDK.getInstance().credentials.collect { credentialsList ->
        val errors = credentialsList.flatMap { it.errors }
        errors.forEach { error ->
            when (error) {
                is SeamCredentialError.Expired -> { /* handle expiration */ }
                is SeamCredentialError.Loading -> { /* handle not loaded yet */ }
                is SeamCredentialError.Unknown -> { /* handle unknown error */ }
                is SeamCredentialError.UserInteractionRequired -> {
                    handleUserInteractionRequired(error.interaction)
                }
            }
        }
    }
}
See also: SeamCredential

isActivated

Whether the SDK is currently activated. Emits true after a successful activate() call and false after deactivate().
val isActivated: StateFlow<Boolean>
Latest value is always available via .value.
lifecycleScope.launch {
    seamSDK.isActivated.collect { activated ->
        updateActivationUI(activated)
    }
}

unlockStatus

The current status of the unlock operation. Emits SeamUnlockEvent instances as unlock operations progress.
val unlockStatus: StateFlow<SeamUnlockEvent>
The flow retains the latest event, accessible via .value. Subscribe to this flow before calling unlock() to ensure no events are missed.
lifecycleScope.launch {
    seamSDK.unlockStatus.collect { event ->
        when (event) {
            is SeamUnlockEvent.ScanningStarted -> showScanningUI()
            is SeamUnlockEvent.AccessGranted -> showSuccessUI()
            is SeamUnlockEvent.Timeout -> showTimeoutError()
            is SeamUnlockEvent.ReaderError -> showReaderError(event.message)
        }
    }
}
See also: SeamUnlockEvent

Suspend Methods

activate()

Activates the SDK by syncing with the server and setting up background services. Requires an active internet connection on first activation. Safe to call multiple times — subsequent calls are no-ops if already activated. After successful activation, isActivated emits true and credentials begin syncing automatically.
suspend fun activate()
Throws
ErrorDescription
SeamError.InitializationRequiredinitialize() has not been called.
SeamError.InternetConnectionRequiredNo internet connection is available.
SeamError.InvalidClientSessionTokenThe client session token is invalid.
val seamSDK = SeamSDK.getInstance()
try {
    seamSDK.activate()
} catch (seamError: SeamError) {
    when (seamError) {
        is SeamError.InitializationRequired -> {
            // handle error when SDK is not initialized
        }
        is SeamError.InternetConnectionRequired -> {
            // handle error when internet connection is required
        }
        is SeamError.InvalidClientSessionToken -> {
            // handle error when client session token is invalid
        }
        else -> {
            // handle other errors
        }
    }
}

deactivate(deintegrate)

Deactivates the SDK. Stops background operations and releases resources. Credentials remain cached and available for the next activation. Safe to call multiple times.
suspend fun deactivate(deintegrate: Boolean = false)
Parameters
ParameterTypeDefaultDescription
deintegrateBooleanfalseIf true, removes the device association and clears all state.
Throws
ErrorDescription
SeamError.InitializationRequiredinitialize() has not been called.
SeamError.DeactivationInProgressA deactivation is already in progress.
val seamSDK = SeamSDK.getInstance()
try {
    seamSDK.deactivate(deintegrate = true)
} catch (seamError: SeamError) {
    when (seamError) {
        is SeamError.InitializationRequired -> {
            // handle error when SDK is not initialized
        }
        is SeamError.DeactivationInProgress -> {
            // handle error when deactivation is already in progress
        }
        else -> {
            // handle other errors
        }
    }
}

refresh()

Manually syncs credentials with the server and updates the credentials StateFlow. Requires an active internet connection. In most cases, automatic background sync makes manual refresh unnecessary.
suspend fun refresh(): List<SeamCredential>
Returns: The updated list of SeamCredential objects after the refresh completes. Throws
ErrorDescription
SeamError.InitializationRequiredinitialize() has not been called.
SeamError.DeactivationInProgressA deactivation is in progress.
val seamSDK = SeamSDK.getInstance()
try {
    val updatedCredentials = seamSDK.refresh()
} catch (seamError: SeamError) {
    when (seamError) {
        is SeamError.InitializationRequired -> {
            // handle error when SDK is not initialized
        }
        is SeamError.DeactivationInProgress -> {
            // handle error when app is being deactivated
        }
        else -> {
            // handle other errors
        }
    }
}

Non-Suspend Methods

unlock(credentialId, unlockProximity?, timeout?)

Initiates an unlock operation for the specified credential. Progress events are emitted to the unlockStatus StateFlow. The operation continues even if the app moves to the background. Works offline if credentials are already cached.
fun unlock(
    credentialId: CredentialId,
    unlockProximity: UnlockProximity? = null,
    timeout: Duration? = null
): Job
CredentialId is a type alias for String. Parameters
ParameterTypeDefaultDescription
credentialIdCredentialIdThe credential ID to unlock.
unlockProximityUnlockProximity?nullThe required proximity for this attempt. If null, uses the provider default (the first value in SeamCredential.supportedUnlockProximities).
timeoutDuration?nullMaximum time to wait for the unlock operation. If null, uses the provider default.
Returns: A Job that can be used to cancel the unlock operation. Throws
ErrorDescription
SeamError.InitializationRequiredinitialize() has not been called.
SeamError.ActivationRequiredThe SDK has not been activated.
SeamError.IntegrationNotFoundNo integration found for the credential’s provider.
SeamError.InvalidCredentialIdThe credential ID is not recognized by the SDK.
SeamError.CredentialErrorsThe credential has one or more unresolved errors.
SeamError.InvalidUnlockProximityThe specified unlock proximity is not supported by this credential.
val seamSDK = SeamSDK.getInstance()

// Start collecting unlock events before calling unlock
coroutineScope.launch {
    seamSDK.unlockStatus.collect { event ->
        when (event) {
            is SeamUnlockEvent.ScanningStarted -> { /* handle scanning started */ }
            is SeamUnlockEvent.AccessGranted -> { /* handle access granted */ }
            is SeamUnlockEvent.Timeout -> { /* handle timeout */ }
            is SeamUnlockEvent.ReaderError -> { /* handle reader error */ }
        }
    }
}

// Perform unlock
try {
    seamSDK.unlock(
        credentialId = credential.id!!,
        unlockProximity = UnlockProximity.TOUCH,
        timeout = 30.seconds
    )
} catch (seamError: SeamError) {
    when (seamError) {
        is SeamError.ActivationRequired -> { /* SDK not activated */ }
        is SeamError.CredentialErrors -> {
            handleCredentialErrors(seamError.errors)
        }
        is SeamError.InitializationRequired -> { /* SDK not initialized */ }
        is SeamError.IntegrationNotFound -> { /* provider not found */ }
        is SeamError.InvalidCredentialId -> { /* bad credential ID */ }
        else -> { /* handle other errors */ }
    }
}
See also: UnlockProximity, SeamUnlockEvent, SeamError

listCredentials()

Returns the current credential list synchronously. If the SDK has not been initialized, returns an empty list.
fun listCredentials(): List<SeamCredential>
Returns: The current list of SeamCredential objects.
val credentials = seamSDK.listCredentials()

setUnlockEventListener(listener)

Registers a callback to receive unlock events as an alternative to collecting the unlockStatus StateFlow.
fun setUnlockEventListener(listener: (SeamUnlockEvent) -> Unit)
Parameters
ParameterTypeDescription
listener(SeamUnlockEvent) -> UnitA lambda invoked for each unlock event.
seamSDK.setUnlockEventListener { event ->
    when (event) {
        is SeamUnlockEvent.ScanningStarted -> showScanningUI()
        is SeamUnlockEvent.AccessGranted -> showSuccessUI()
        is SeamUnlockEvent.Timeout -> showTimeoutError()
        is SeamUnlockEvent.ReaderError -> showReaderError(event.message)
    }
}

setCredentialsListener(listener)

Registers a callback to receive credential list updates as an alternative to collecting the credentials StateFlow.
fun setCredentialsListener(listener: (List<SeamCredential>) -> Unit)
Parameters
ParameterTypeDescription
listener(List<SeamCredential>) -> UnitA lambda invoked whenever the credential list changes.
seamSDK.setCredentialsListener { credentials ->
    updateCredentialList(credentials)
}

setNotification(notification)

Sets the foreground service notification used during unlock scanning. Required for Assa Abloy foreground scanning.
fun setNotification(notification: Notification)
Parameters
ParameterTypeDescription
notificationNotificationThe notification to display while the foreground service is running.
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
    .setContentTitle("Scanning for doors…")
    .setSmallIcon(R.drawable.ic_lock)
    .build()

seamSDK.setNotification(notification)