Onfido Studio: Android SDK integration
Start here
This is an introductory guide to integrating Onfido Studio - our drag and drop interface for building, managing, and deploying identity verification journeys - with Onfido’s Android SDK. For more general information regarding Onfido Studio, please see our product guide.
Getting started
All of the interactive tasks of an end-user’s verification journey designed and built using Onfido Studio are managed by our SDKs.
The Onfido Android SDK communicates directly and dynamically with active Studio workflows to display the relevant screens to ensure the correct capture and upload of user information, such as identity documents, selfie photos and videos. As a result, the SDK flow will vary depending on the workflow configuration. You won't need to specify any steps directly in the SDK integration as these will be overridden when the workflow run ID is passed into the SDK initialization.
The Android SDK supports API level 21 and above. Our configuration is currently set to the following:
minSdkVersion = 21
targetSdkVersion = 31
android.useAndroidX=true
Kotlin = 1.3+
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Create a workflow run
As a first step, you will need to create a Workflow Run by making a call to the Onfido API. At a minimum, you will need to provide a workflow_id
from a valid, active workflow, as well as an Applicant ID. More details on creating a workflow run can be found in our API reference.
The server will return a workflow run object, with a workflow run ID contained in the response:
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<WORKFLOW_RUN_ID>",
"applicant_id": "<APPLICANT_ID>",
"workflow_id": "<WORKFLOW_ID>",
"workflow_version_id": 11,
"status": "approved",
"dashboard_url":"https://dashboard.onfido.com/results/<WORKFLOW_RUN_ID>"
"output": {"prop1": "val_1", "prop2": 10},
"reasons": ["reason_1", "reason_2"],
"error": null,
"created_at": "2022-06-28T15:39:42Z",
"updated_at": "2022-07-28T15:40:42Z",
"link": {
"completed_redirect_url": "https://example.onfido.com",
"expired_redirect_url": "https://example.onfido.com",
"expires_at": "2022-10-17T14:40:50Z",
"language": "en_US",
"url": "https://eu.onfido.app/l/<WORKFLOW_RUN_ID>"
},
}
Generate an SDK token
SDK tokens are required to authenticate the SDKs for Studio workflows, generated by making a call to the Onfido API.
$ curl https://api.eu.onfido.com/v3.6/sdk_token \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-F 'applicant_id=<APPLICANT_ID>' \
-F 'application_id=<YOUR_APPLICATION_BUNDLE_IDENTIFIER>'
SDK tokens expire after 90 minutes. You can use the optional tokenExpirationHandler
parameter in the SDK token configurator function to generate and pass a new SDK token when it expires. This ensures the SDK continues its flow even after an SDK token has expired. You should inject a new token in 10 seconds after the callback is triggered, otherwise the flow will finish with a TokenExpiredException
error.
Kotlin
class ExpirationHandler : TokenExpirationHandler {
override fun refreshToken(injectNewToken: (String?) -> Unit) {
TODO("<Your network request logic to retrieve SDK token goes here>")
injectNewToken("<NEW_SDK_TOKEN>") // if you pass `null` the sdk will exit with token expired error
}
}
val config = OnfidoConfig.builder(context)
.withSDKToken("<YOUR_SDK_TOKEN_HERE>", tokenExpirationHandler = ExpirationHandler()) // ExpirationHandler is optional
Java
class ExpirationHandler implements TokenExpirationHandler {
@Override
public void refreshToken(@NotNull Function1<? super String, Unit> injectNewToken) {
//Your network request logic to retrieve SDK token goes here
injectNewToken.invoke("<NEW_SDK_TOKEN>"); // if you pass `null` the sdk will exit with token expired error
}
}
OnfidoConfig.Builder config = new OnfidoConfig.Builder(context)
.withSDKToken("<YOUR_SDK_TOKEN>", new ExpirationHandler()); // ExpirationHandler is optional
More detailed documentation about SDK tokens can be found in our API reference.
Add the SDK dependency
Onfido-capture-sdk
is the recommended integration option.
repositories {
mavenCentral()
}
dependencies {
implementation 'com.onfido.sdk:onfido-workflow:x.y.z'
}
Multi-APK split
C++ code needs to be compiled for each of the CPU architectures (known as "ABIs") present on the Android environment. Currently, the SDK supports the following ABIs:
armeabi-v7a
: Version 7 or higher of the ARM processor. Most recent Android phones use thisarm64-v8a
: 64-bit ARM processors. Found on new generation devicesx86
: Most tablets and emulatorsx86_64
: Used by 64-bit tablets
The SDK binary contains a copy of the native .so
file for each of these four platforms. You can considerably reduce the size of your .apk
by applying APK split by ABI, editing your build.gradle
to the following:
android {
splits {
abi {
enable true
reset()
include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a'
universalApk false
}
}
}
Read the Android documentation for more information.
Initialize the SDK for Studio
Now you can initialize the SDK, using your generated SDK token and workflow run ID.
Build a configuration object
const val REQUEST_CODE = 0x05
private lateinit var onfidoWorkflow: OnfidoWorkflow
fun onCreate(savedInstanceState: Bundle?) {
val workflowConfig = WorkflowConfig.Builder(
workflowRunId = "<WORKFLOW_RUN_ID>",
sdkToken = "<SDK_TOKEN>"
).build()
}
Start the flow
onfidoWorkflow = OnfidoWorkflow.create(this)
startActivityForResult(onfidoWorkflow.createIntent(workflowConfig), REQUEST_CODE)
Handling callbacks
To receive the result from a completed workflow, you should override the method onActivityResult
on your Activity/Fragment. The following code is provided as an example:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
onfidoWorkflow.handleActivityResult(resultCode, data, object : OnfidoWorkflow.ResultListener {
override fun onUserCompleted() {
// Called when the entire workflow run has reached the terminal node.
}
override fun onUserExited(exitCode: ExitCode) {
// Called when the user has exited the flow prematurely.
}
override fun onException(exception: OnfidoWorkflow.WorkflowException) {
// Called when the flow has ended with an exception
}
})
}
ATTRIBUTE | NOTES |
---|---|
onUserCompleted | Callback that fires when all interactive tasks in the workflow have been completed. If you have configured webhooks, a notification will be sent to your backend confirming the workflow run has finished. You do not need to create a check using your backend as this is handled directly by the workflow |
onUserExited | Callback that fires when the workflow was exited prematurely by the user. The reason can be an exitCode, e.g USER_CONSENT_DENIED |
onException | In case of an unexpected error, the onException method will be invoked with a relevant error message in the WorkflowException object. Error messages are not in a presentable format to the end user and are not localised |
Error handling
The exception
object returned as part of onException(exception)
is of type WorkflowException
.
It's a sealed class with multiple cases, depending on the exception type.
override fun onException(exception: OnfidoWorkflow.WorkflowException) {
when (exception) {
is WorkflowInsufficientVersionException ->
// This happens when you are using an older version of the Android SDK and trying
// to access a new functionality from workflow. You can fix this by updating the SDK
is WorkflowInvalidSSLCertificateException ->
// When network requests fail because SSL certificate is invalid
is WorkflowTokenExpiredException ->
// When SDK token is expired and needs to be refreshed
is WorkflowUnknownCameraException ->
// When some unknown camera exception happens.
is WorkflowUnknownResultException ->
// When an corrupted intent result is passed to the SDK
is WorkflowUnsupportedTaskException ->
// This happens when you are using an older version of the Android SDK.
// You can fix this by updating the SDK
is WorkflowHttpException ->
// This happens when the SDK receives an error from an API call
// see https://documentation.onfido.com/#errors for more information
is WorkflowUnknownException ->
// This happens when an unexpected error occurs.
// Please contact android-sdk@onfido.com when this happens
else ->
// Necessary because of Kotlin
}
}
Customizing the SDK
The Android SDK has multiple customizable features that provide flexibility, while also being easy to integrate. For more detailed documentation, read our SDK customization guide.
UI Customization
The Android SDK supports the customization of colors and fonts used in the SDK flow. For information regarding the available options, please see our SDK customization guide.
Language localization
The SDK supports and maintains multiple languages. Please refer to the Android SDK language localization documentation for more details.
Note: For localisation, you need to use withLocale(locale: Locale)
method of
the WorkflowConfig.Builder
to set the preferred locale.