# Callbacks and handlers for Android SDK
# SDK state change notification
To receive notifications about SDK state changes, use .withHandlers(onStateChanged = onSDKStateChangedHandler) or .withStateChangedHandler(stateChangedHandler) in CBRMobileSDK.Builder.
The handler receives two parameters:
newState— the current SDK state.prevState— the previous SDK state.
Example listing all possible states:
val onSDKStateChangedHandler: (CBRSDKState, CBRSDKState) -> Unit = { newState, prevState ->
Timber.d("onSDKStateChangedHandler: $prevState -> $newState")
when (newState) {
is CBRSDKState.Ready -> Timber.d("SDK is ready")
is CBRSDKState.Failed -> {
when (newState) {
is CBRSDKState.Failed.ApplicantNotFound -> Timber.e(newState.message)
is CBRSDKState.Failed.ApplicantMisconfigured -> Timber.e(newState.message)
is CBRSDKState.Failed.InitialLoadingFailed -> Timber.e(newState.exception,"Initial loading error")
is CBRSDKState.Failed.InvalidParameters -> Timber.e(newState.message)
is CBRSDKState.Failed.NetworkError -> Timber.e(newState.exception,newState.message)
is CBRSDKState.Failed.Unauthorized -> Timber.e(newState.exception,"Invalid token or a token can't be refreshed by the SDK. Please, check your token expiration handler")
is CBRSDKState.Failed.Unknown -> Timber.e(newState.exception, "Unknown error")
}
}
is CBRSDKState.Initial -> Timber.d("No verification steps are passed yet")
is CBRSDKState.Incomplete -> Timber.d("Some but not all verification steps are passed over")
is CBRSDKState.Pending -> Timber.d("Verification is in pending state")
is CBRSDKState.FinallyRejected -> Timber.d("Applicant has been finally rejected")
is CBRSDKState.TemporarilyDeclined -> Timber.d("Applicant has been declined temporarily")
is CBRSDKState.Approved -> Timber.d("Applicant has been approved")
}
}
val cbrSdk = CBRMobileSDK.Builder(this).withHandlers(onStateChanged = onSDKStateChangedHandler)
CBRStateChangedHandler stateChangedHandler = (prevState, newState) -> {
Timber.d("The SDK state was changed: " + prevState + " -> " + newState);
if (newState instanceof CBRSDKState.Ready) {
Timber.d("SDK is ready");
} else if (newState instanceof CBRSDKState.Failed.Unauthorized) {
Timber.e(((CBRSDKState.Failed.Unauthorized) newState).getException(), "Invalid token or a token can't be refreshed by the SDK. Please, check your token expiration handler");
} else if (newState instanceof CBRSDKState.Failed.Unknown) {
Timber.e(((CBRSDKState.Failed.Unknown) newState).getException(), "Unknown error");
} else if (newState instanceof CBRSDKState.Initial) {
Timber.d("No verification steps are passed yet");
} else if (newState instanceof CBRSDKState.Incomplete) {
Timber.d("Some but not all verification steps are passed over");
} else if (newState instanceof CBRSDKState.Pending) {
Timber.d("Verification is in pending state");
} else if (newState instanceof CBRSDKState.FinallyRejected) {
Timber.d("Applicant has been finally rejected");
} else if (newState instanceof CBRSDKState.TemporarilyDeclined) {
Timber.d("Applicant has been declined temporarily");
} else if (newState instanceof CBRSDKState.Approved) {
Timber.d("Applicant has been approved");
}
};
CBRMobileSDK.SDK cbrSdk = new CBRMobileSDK.Builder(requireActivity()).withStateChangedHandler(stateChangedHandler).build();
# Event notifications
The event handler allows you to stay informed about events occurring during processing.
Events are passed to the handler as instances of classes derived from the base class CBREvent. Each event therefore has an eventType and a set of parameters packed into a payload dictionary.
Depending on your needs, you can access event parameters either by analyzing the payload directly or by casting the passed event instance to the corresponding CBREvent* class based on its type.
val onEventHandler: CBREventHandler = object : CBREventHandler {
override fun onEvent(event: CBREvent) {
when (event) {
is CBREvent.CBREventStepInitiated -> {
Timber.d("onEvent: step initiated")
}
is CBREvent.CBREventStepCompleted -> {
Timber.d("onEvent: step completed")
}
}
}
}
val cbrSdk = CBRMobileSDK.Builder(this).withEventHandler(onEventHandler)
CBREventHandler eventHandler = cbrEvent -> {
if (cbrEvent instanceof CBREvent.CBREventStepInitiated) {
Timber.d("onEvent: step initiated");
} else if (cbrEvent instanceof CBREvent.CBREventStepCompleted) {
Timber.d("onEvent: step completed");
}
};
CBRMobileSDK.SDK cbrSdk = new CBRMobileSDK.Builder(requireActivity()).withEventHandler(eventHandler).build();
# SDK completion notification
An optional handler to receive notifications when the SDK is closed.
The handler receives two parameters:
result:CBRCompletionResult.SuccessTermination— successful SDK termination, including a call todismiss().CBRCompletionResult.AbnormalTermination— an error occurred during SDK operation. Additional information can be obtained from theexceptionobject.
state: the SDK state at the time of closure. Possible states are listed in SDK state change notification.
val onSDKCompletedHandler: (CBRCompletionResult, CBRSDKState) -> Unit = { (result, state) ->
when (result) {
is CBRCompletionResult.SuccessTermination -> Timber.d("The SDK finished successfully")
is CBRCompletionResult.AbnormalTermination -> Timber.e(result.exception, "The SDK got closed because of errors")
}
}
val cbrSdk = CBRMobileSDK.Builder(this).withHandlers(onCompleted = onSDKCompletedHandler)
CBRCompleteHandler completeHandler = (result, state) -> {
Timber.d("The SDK is finished. Result: " + result + " , State: " + state);
Toast.makeText(applicationContext, "The SDK is finished. Result: $result, State: $state", Toast.LENGTH_SHORT).show();
if (result instanceof CBRCompletionResult.SuccessTermination) {
Timber.d(result.toString());
} else if (result instanceof CBRCompletionResult.AbnormalTermination) {
Timber.d(((CBRCompletionResult.AbnormalTermination) result).getException());
}
};
CBRMobileSDK.SDK cbrSdk = new CBRMobileSDK.Builder(requireActivity()).withCompleteHandler(completeHandler).build();
# Token expiration
Since the access token (accessToken) has a limited lifespan, it is important to be able to refresh it. To do this, pass a tokenHandler to CBRMobileSDK.Builder.
The handler requests a new token from your server and then provides it back to the SDK.
val tokenHandler = object : TokenExpirationHandler {
override fun onTokenExpired(): String? {
val newToken = "..." // obtain a new token from the backend
return newToken
}
}
TokenExpirationHandler tokenUpdater = () -> {
String newAccessToken = "..."; // obtain a new token from the backend
return newAccessToken;
};
Warning:
onTokenExpired should not be called on the UI thread.
# SDK error notification
To receive error notifications, use .withHandlers(onError = onSDKErrorHandler) or .withErrorHandler(errorHandler) in CBRMobileSDK.Builder.
val onSDKErrorHandler: (CBRException) -> Unit = { exception ->
Timber.d("The SDK throws an exception. Exception: $exception")
when (exception) {
is CBRException.Api -> Timber.d("Api exception. ${exception.description}")
is CBRException.Network -> Timber.d(exception, "Network exception.")
is CBRException.Unknown -> Timber.d(exception, "Unknown exception.")
}
}
val cbrSdk = CBRMobileSDK.Builder(this).withHandlers(onError = onSDKErrorHandler)
CBRErrorHandler errorHandler = e -> {
Timber.d("The SDK throws an exception. Exception: %s", e);
if (e instanceof CBRException.Api) {
Timber.d("Api exception. %s", ((CBRException.Api) e).getDescription());
} else if (e instanceof CBRException.Network) {
Timber.d(e, "Network exception.");
} else if (e instanceof CBRException.Unknown) {
Timber.d(e, "Unknown exception.");
}
};
CBRMobileSDK.SDK cbrSdk = new CBRMobileSDK.Builder(requireActivity()).withErrorHandler(errorHandler).build();
# Action result notification
This handler can be used to receive the result of an applicant action and to manage the face liveness check scenario.
The handler receives two parameters:
actionId: String— the identifier of the applicant action.answer: String— the response from the face liveness check module.
Possible values:GREEN/YELLOW/RED/ERROR/null.
The handler should return a CBRActionResult:
CBRActionResult.Continue— continue the default action scenario (for example, show the result screen).CBRActionResult.Cancel— cancel the default action scenario (close the SDK without showing the result screen).
val onActionResultHandler: CBRActionResultHandler = object : CBRActionResultHandler {
override fun onActionResult(actionId: String, actionType: String, answer: String?, allowContinuing: Boolean): CBRActionResult {
Timber.d("Face Auth action result: actionId: $actionId answer: $answer")
// use the default action scenario
return CBRActionResult.Continue
}
}
val cbrSdk = CBRMobileSDK.Builder(this).withActionResultHandler(onActionResult)
CBRActionResultHandler actionResultHandler = (actionId, actionType, answer, allowContinuing) -> {
Timber.d("Action Result: actionId: " + actionId + ", answer: " + answer);
return CBRActionResult.Continue;
};
CBRMobileSDK.SDK cbrSdk = new CBRMobileSDK.Builder(requireActivity()).withActionResultHandler(actionResultHandler).build();
# Icon handler
This handler allows you to customize icons on IDnGO SDK screens. Currently, only instruction icons and document icons (for the document selection screen) are supported.
The handler provides the icon key and thematic context, returning a drawable or null if no drawable is required.
SDK uses the following keys:
default/do_idCard— icon for identity document instructions (instruction screen, DO block).default/dont_idCard— icon for identity document instructions (instruction screen, DON'T block).default/do_idCard_backSide— icon for instructions for the back side of the identity document (instruction screen, DO block).default/dont_idCard_backSide— icon for instructions for the back side of the identity document (instruction screen, DON'T block).default/do_passport— icon for passport instructions (instruction screen, DO block).default/dont_passport— icon for passport instructions (instruction screen, DON'T block).default/facescan— icon for face liveness check instructions.IdentityType/<DOCUMENT TYPE>— icon for a document item on the document selection screen, where<DOCUMENT TYPE>can bePASSPORT,DRIVERS,RESIDENCE_PERMIT, or another document.Flag/<COUNTRY_CODE>— icon for a country flag, where<COUNTRY_CODE>is the Alpha-2 code (ISO 3166-1).
You can provide your own icons or override existing ones by extending CBRDefaultIconHandler.
val iconHandler = object : CBRIconHandler {
override fun onResolveIcon(context: Context, key: String): Drawable? {
val iconRes = when {
key == "default/do_idCard" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_intro_do
key == "default/do_passport" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_intro_do_passport
key == "default/dont_idCard" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_intro_dont
key == "default/dont_passport" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_intro_dont_passport
key == "default/facescan" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_intro_liveness
key == "default/do_idCard_backSide" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_intro_do_back
key == "default/dont_idCard_backSide" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_intro_dont_back
key == "IdentityType/PASSPORT" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_iddoc_passport
key == "IdentityType/DRIVERS" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_iddoc_driving_license
key == "IdentityType/RESIDENCE_PERMIT" -> ru.cyberity.cbr.core.R.drawable.cbr_ic_iddoc_residence_permit
key.startsWith("IdentityType/") -> ru.cyberity.cbr.core.R.drawable.cbr_ic_iddoc_id_card
else -> -1
}
return iconRes.takeIf { it != -1 }?.let { ResourcesCompat.getDrawable(context.resources, it, context.theme) }
}
}
val cbrSdk = CBRMobileSDK.Builder(this).withIconHandler(iconHandler)