@@ -37,6 +37,18 @@ let credentialsSubscription = Seam.shared.$credentials
3737 }
3838```
3939{% endtab %}
40+
41+ {% tab title="Android Kotlin" %}
42+ ``` kotlin
43+ import co.seam.core.api.SeamCredential
44+ import co.seam.core.api.SeamSDK
45+
46+ // Collect credentials
47+ SeamSDK .getInstance().credentials.collect { credentials ->
48+ // Update UI with new credentials array.
49+ }
50+ ```
51+ {% endtab %}
4052{% endtabs %}
4153
4254## 2. Monitor Credential Errors
@@ -57,6 +69,38 @@ let errorSubscription = Seam.shared.$credentials
5769 }
5870```
5971{% endtab %}
72+ {% tab title="Android Kotlin" %}
73+ ``` kotlin
74+ import co.seam.core.api.SeamCredential
75+ import co.seam.core.api.SeamSDK
76+ import co.seam.core.sdkerrors.SeamCredentialError
77+ import co.seam.core.sdkerrors.SeamError
78+ import co.seam.core.sdkerrors.SeamRequiredUserInteraction
79+
80+ SeamSDK .getInstance().credentials.collect { credentialsList ->
81+ val errors = credentialsList.flatMap { it.errors }
82+ errors.forEach { error ->
83+ when (error) {
84+ is SeamCredentialError .Expired -> { /* handle credential expiration error */ }
85+ is SeamCredentialError .Loading -> { /* handle not loaded yet */ }
86+ is SeamCredentialError .Unknown -> { /* handle unknown error */ }
87+ is SeamCredentialError .UserInteractionRequired -> {
88+ handleUserInteractionRequired(error.interaction)
89+ }
90+ }
91+ }
92+ }
93+
94+ fun handleUserInteractionRequired (interaction : SeamRequiredUserInteraction ) {
95+ when (interaction) {
96+ is SeamRequiredUserInteraction .CompleteOtpAuthorization -> { /* handle OTP authorization */ }
97+ is SeamRequiredUserInteraction .EnableBluetooth -> { /* handle Bluetooth error */ }
98+ is SeamRequiredUserInteraction .EnableInternet -> { /* handle Internet connection error*/ }
99+ is SeamRequiredUserInteraction .GrantPermissions -> { /* handle permissions error*/ }
100+ }
101+ }
102+ ```
103+ {% endtab %}
60104{% endtabs %}
61105
62106> ** Note:** The ` .errors ` array on credentials represents per-credential issues, though some issues may be repeated across several credentials (for example, bluetooth requirements). SDK- or credential-level errors (such as invalid token or expired credential) are thrown directly by methods like ` unlock(using:) ` because ` SeamError ` or ` SeamCredentialError ` and must be handled through ` do/catch ` .
@@ -118,6 +162,82 @@ do {
118162 // Handle unlock initialization error.
119163 print (" Unlock error: \( error ) " )
120164}
165+ ```
166+ {% endtab %}
167+ {% tab title="Android Kotlin" %}
168+ ``` kotlin
169+ import co.seam.core.api.SeamCredential
170+ import co.seam.core.api.SeamSDK
171+ import co.seam.core.events.SeamUnlockEvent
172+ import co.seam.core.sdkerrors.SeamCredentialError
173+ import co.seam.core.sdkerrors.SeamError
174+ import co.seam.core.sdkerrors.SeamRequiredUserInteraction
175+
176+ val seamSDK = SeamSDK .getInstance()
177+
178+ // Perform unlock
179+ try {
180+ val credentialId = credential.id
181+ // Timeout is optional
182+ seamSDK.unlock(
183+ credentialId = credentialId,
184+ timeout = 30 .seconds
185+ )
186+ } catch (seamError: SeamError ) {
187+ when (seamError) {
188+ is SeamError .ActivationRequired -> {
189+ // handle error when SDK is not activated
190+ }
191+ is SeamError .CredentialErrors -> {
192+ val credentialErrors = seamError.errors
193+ handleCredentialErrors(credentialErrors)
194+ // handle error when there are credential errors
195+ }
196+ is SeamError .InitializationRequired -> {
197+ // handle error when SDK is not initialized
198+ }
199+ is SeamError .IntegrationNotFound -> {
200+ // handle error when integration is not found, Such as Assa Abloy, Latch and Salto
201+ }
202+ is SeamError .InternetConnectionRequired -> {
203+ // handle error when internet connection is required
204+ }
205+ is SeamError .InvalidClientSessionToken -> {
206+ // handle error when client session token is invalid
207+ }
208+ else -> {
209+ // handle other errors
210+ }
211+ }
212+ }
213+
214+ // Handle credential errors on unlock
215+ fun handleCredentialErrors (credentialErrors : List <SeamCredentialError >) {
216+ credentialErrors.forEach { credentialError ->
217+ when (credentialError) {
218+ is SeamCredentialError .Invalid -> {
219+ // handle error when credential is invalid
220+ }
221+
222+ is SeamCredentialError .Expired -> {
223+ // handle error when credential is expired
224+ }
225+
226+ is SeamCredentialError .Loading -> {
227+ // handle error when credential is not loaded yet
228+ }
229+
230+ is SeamCredentialError .UserInteractionRequired -> {
231+ // handle user interaction required credential error
232+ }
233+
234+ is SeamCredentialError .Unknown -> {
235+ // handle unknown credential error
236+ }
237+ }
238+ }
239+ }
240+
121241```
122242{% endtab %}
123243{% endtabs %}
@@ -192,6 +312,24 @@ do {
192312}
193313```
194314{% endtab %}
315+
316+ {% tab title="Android Kotlin" %}
317+ ``` kotlin
318+ // Start collecting unlock events before unlock
319+ coroutineScope.launch {
320+ seamSDK.unlockStatus.collect { event ->
321+ when (event) {
322+ is SeamUnlockEvent .ScanningStarted -> { /* handle scanning started */ }
323+ is SeamUnlockEvent .Connecting -> { /* handle connecting */ }
324+ is SeamUnlockEvent .AccessGranted -> { /* handle access granted */ }
325+ is SeamUnlockEvent .Timeout -> { /* handle timeout */ }
326+ is SeamUnlockEvent .ReaderError -> { /* handle reader error */ }
327+ else -> { /* handle other events */ }
328+ }
329+ }
330+ }
331+ ```
332+ {% endtab %}
195333{% endtabs %}
196334
197335## 5. Cancel the Unlock Operation
0 commit comments