Verifai Android SDK (v4.4.0)
Welcome to the Verifai Android SDK implementation documentation. If you have any questions that are unanswered you can always contact our support.
This documentation will continue to expand as extra services will be added.
Older versions
If you're looking for documentation for previous versions of Verifai then check below:
Core version | Link |
---|---|
4.3.4 |
Documentation |
4.3.3 |
Documentation |
4.2.0 |
Documentation |
3.3.4 |
Documentation |
3.3.3 |
Documentation |
Quick start
In the quick start implementation guide we describe the fastest way to implement our SDK.
This is the high level process:
- Add the dependencies with Gradle
- Obtain a licence
- Add some code to your project to start the process
- Add some permissions to your
AndroidManifest.xml
When you have done that, the Verifai software is integrated into your very own Android app.
Obtain a licence
Verifai only works with a valid licence. Obtaining a Verifai licence works the same for all platforms. The licence can be found in the Verifai dashboard. Need more information? Please read the guide in the general docs.
The Android SDK uses the package name that has been declared in your apps
Manifest.xml
file as the licence identifier. Please make sure that this
identifier has been added to your licence. This can be done in the Verifai Dashboard. An incorrect licence will result
in a LicenceNotValidException
.
Add dependencies via Gradle
The distribution of the SDK and its components is done via a Maven web-service. This should be the easiest way to integrate the Verifai SDK into your app. Please copy and paste from the code example:
api 'com.verifai:core:4.4.0'
implementation 'com.verifai:nfc:4.4.0'
implementation 'com.verifai:liveness-check:4.4.0'
implementation 'com.verifai:manual-data-crosscheck:4.4.0'
implementation 'com.verifai:manual-security-features-check:4.4.0'
These packages can only be found when Verifai's maven repository has
been added to the project's build.gradle
file:
allprojects {
repositories {
google()
jcenter()
maven { url = 'https://dashboard.verifai.com/downloads/sdk/maven/' }
}
}
Add the code
Verifai can be configured and started with just a few lines of code. The minimal needed code for implementing Verifai is as stated here.
Verifai.setLicence(licenceString) // The licence string that has been obtained from the dashboard.
Verifai.startScan(this, object : VerifaiResultListener {
override fun onSuccess(result: VerifaiResult) {
// Handle the result. Please consult the general docs for more information regarding the result object and its contents.
}
override fun onCanceled() {
// What to do when the user cancels the SDK route.
// This will mostly be triggered because of the user pressing the back button
// or locking the phone in certain states.
// The user can restart Verifai from the start. No errors occurred.
}
override fun onError(e: Throwable) {
if (e is LicenceNotValidException) {
// The licence is not working. Please get the correct licence from the dashboard.
Log.d("Authentication", "Authentication failed")
}
}
})
String licence = "=== Verifai Licence file V2 ===\n" +
Verifai.setLicence(this, licence); // The licence string that has been obtained from the dashboard.
VerifaiResultListener resultListener = new VerifaiResultListener() {
@Override
public void onCanceled() {
// What to do when the user cancels the SDK route.
// This will mostly be triggered because of the user pressing the back button
// or locking the phone in certain states.
// The user can restart Verifai from the start. No errors occurred.
}
@Override
public void onSuccess(VerifaiResult verifaiResult) {
// Handle the result. Please consult the general docs for more information regarding the result object and its contents.
}
@Override
public void onError(@NotNull Throwable throwable) {
Log.d("error", throwable.getMessage());
}
};
Verifai.startScan(this, resultListener);
Configuration options can be added. More detailed information about configuration options can be found over here.
The Verifai Android SDK example code on GitHub might help while implementing the SDK. The example code can be found over here.
Add permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.hardware.camera.autofocus" />
Verifai needs an internet connection and a camera to work. These features rely on permissions. Therefore the following permissions should be declared in the AndroidManifest.xml
file of your app.
Why are the permissions needed
Verifai has been built with privacy in mind. This is why Verifai wants to be clear about the permissions it uses. This paragraph explains why the permissions are needed. Please point any questions regarding privacy towards our support team.
The internet permission
The internet permission is needed so the Verifai SDK can download advanced neural networks to recognize and read documents. This permission is also needed to let the user pick between documents since these documents are getting retrieved from Verifai's databases.
The camera permission
Verifai uses the device's camera to recognize, and read from, documents. The cameras are the eyes of the device. To prevent developers from spying on users they need to ask permission for usage first. The user will see a dialog with the question if the camera may be used.
The autofocus permission
Verifai uses intelligence autofocus to capture the documents as clear as possible. The app needs to have the autofocus permission stated in its manifest file to guarantee clear and readable images.
Reading the NFC chip
Simply add the snippet. Make sure that the document has been scanned before reading the chip. Otherwise there is not enough information to read the chip inside the document.
val nfcListener = object : VerifaiNfcResultListener {
override fun onResult(result: VerifaiNfcResult) {
Verifai.logger?.log("NFC Completed")
}
override fun onCanceled() {}
override fun onError(e: Throwable) {}
}
verifaiResult?.let {
VerifaiNfc.start(this, it, true, nfcListener)
}
Performing a liveness check
Some checks can be executed to check if a person is actually a person and not a robot.
start_liveness_button.setOnClickListener {
VerifaiLiveness.start(this, null, object : VerifaiLivenessCheckListener {
override fun onResult(results: VerifaiLivenessCheckResults) { }
override fun onError(e: Throwable) { }
})
}
Detailed documentation
If your use case or environment is more complicated you can use this more in detail part of the documentation. For most situations however the Quick start would be sufficient.
Styling and theming
It is possible to change Verifai's colors to match your app's styling. All colors have been defined in Verifai's resource files and can be overwritten. Please consult Styling and theming
in the general docs to find the color that needs to be overwritten.
All the Verifai color names have been prefixed with Verifai
on Android. This to prevent collisions between color names in multiple resource files. So BottomBoxBackgroundColor
will be VerifaiBottomBoxBackgroundColor
on Android. These renewed color definitions will go in your apps res/values/colors.xml
file like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#FF576D</color>
<color name="backgroundColor">#FFFFFF</color>
<color name="VerifaiBottomBoxBackgroundColor">Your color. E.g. #000000</color>
</resources>
The Android operating system supports dark themes, also known as "dark mode" or "night mode" in all Android versions starting from Android 10. Overwriting these colors work the same as setting the main colors. Just define the colors in res/values-night/colors.xml
instead of res/values/colors.xml
. The color identifying keys are the same.
Overwriting instruction videos
It is possible to replace the instruction videos that can be found throughout the app. These videos guide the users through the screens. However, they may not be fitting into your brand's style. Since these video's have been added as Android resources they can easily be overwritten at compile time. Just add your video to your res/
folder. Make sure that it has the same name as the identifiers mentioned below.
File name | Where it can be found | Object type |
---|---|---|
illustration_of_mrz_video | The first video when the SDK is open and the automatic mode has been enabled | Video |
mrz_scan_instruction_video | The video that shows up as the first video when automatic mode has been enabled. This also shows up when in automatic mode and tapping the "Other country" button. | Video |
fully_automatic_scan_instruction_video | Video that explains how to scan via the automatic mode | Video |
document_scan_fallback_instruction_video | The video that shows up when tapping the button that appears when having trouble scanning. | Video |
nfc_passport_scan_instruction_video | Shows up in the NFC instruction screen when reading a passport | Video |
nfc_id_card_scan_\instruction_video | Shows up in the NFC instruction screen when reading a document that is not a passport | Video |
nfc_passport_scan_fallback_instruction_video | Shows up when the NFC tag disconnects in the middle of the reading process while scanning a passport | Video |
nfc_id_card_scan_fallback_instruction_video | Shows up when the NFC tag disconnects in the middle of the reading process while scanning a document that is not a passport | Video |
Customizing instruction screens (beta)
⚠️ This functionality is still in beta mode. Please report any issues to our support team.
The Verifai SDK contains multiple instruction / information screens throughout the flow. We fully understand that these screens might not fit into your product's copy or branding. That is why Verifai 4.4.0 contains support for instruction screen modification. From now on it is possible to set each instruction screen differently. It is possible to keep screens in the same style but with different copy, to add a webpage or to hide a single instruction screen. This can be done via a key-value system combined with varargs.
Every instruction screen has its own key.
- MRZ_PRESENT_FLOW_INSTRUCTION → MRZ scanning flow, first instruction screen
- MRZ_SCAN_FLOW_INSTRUCTION → MRZ scanning flow, second instruction screen
- AUTOMATIC_SCAN_FLOW_INSTRUCTION → Shown when the automatic scan flow has been initialized
- MRZ_NOT_DETECTED_HINT → Shown when pressing the button in the MRZ not found box
- DOCUMENT_PICKER_HELP → Shown when pressing the question mark in the document picker
And its own type.
- DEFAULT → Will show Verifai's default instruction screen
- MEDIA → A screen that can be modified. Please read further for more information
- WEB → Will show a webview
- HIDDEN → Will hide the instruction screen
These keys and types can be added to the instructionScreenConfiguration
configuration parameters' map. For example (see code box).
instructionScreenConfiguration = VerifaiInstructionScreenConfiguration(
true,
mapOf(
Pair(
VerifaiInstructionScreenId.MRZ_SCAN_FLOW_INSTRUCTION,
VerifaiSingleInstructionScreen(VerifaiInstructionType.HIDDEN)
),
Pair(
VerifaiInstructionScreenId.DOCUMENT_PICKER_HELP,
VerifaiSingleInstructionScreen(VerifaiInstructionType.WEB, "https://verifai.com/")
),
Pair(
VerifaiInstructionScreenId.AUTOMATIC_SCAN_FLOW_INSTRUCTION,
VerifaiSingleInstructionScreen(VerifaiInstructionType.DEFAULT)
)
)
)
The VerifaiSingleInstructionScreen
takes variable arguments (varargs) as its "second" parameter. So it is possible to add as many parameters as needed. These parameters will fill or replace the views and texts from top to bottom in the screens. For the media screens the following number of parameters can be used:
Variable order | What it changes | Note |
---|---|---|
1 | The activity title | Only supports a string value |
2 | The string header | |
3 | The video | Only supports a video resource ID |
4 | The text underneath the video | |
5 | The top button | |
6 | The bottom button, will be left out when it does not have a value |
The variables without an added note in the table above support view objects and objects that contain .toString()
methods. Due to safety concerns all listeners will be removed and replaced.
The web type only takes one parameter, that is the url that the webview should show.
ProGuard and code optimisation
Verifai is fully compatible with ProGuard and Google's latest R8
compiler. Bringing even more privacy, security and code optimizations to all ProGuard enabled app builds. All that is needed is to add the
following code to your app's build.gradle
file.
shrinkResources true
minifyEnabled true
Verifai has already been shrunk and obfuscated on build time. So please exclude these from getting obfuscated again. This can be done by adding the following lines to your ProGuard file:
-keep class com.verifai.core.** { *; }
-keep class com.verifai.nfc.** { *; }
-keep class com.verifai.liveness.** { *; }
It is recommended to distribute your app as an Android App Bundle (aab). Aab's give Google Play the possibility to distribute apps for specific hardware architectures and screen sizes. Resulting in smaller installation sizes because the end user will only receive the resources that are needed to run the app on its specific hardware.
Attaching a logger
Verifai.logger = object : VerifaiLogger {
private val tag = javaClass.simpleName
override fun log(e: Throwable) {
Log.e(tag, Log.getStackTraceString(e))
Sentry.capture(e) // Example when using Sentry, can basically be anything.
}
override fun log(event: String) {
Log.i(tag, event)
Sentry.capture(event) // Example when using Sentry, can basically be anything.
}
}
Verifai.logger = new VerifaiLogger() {
@Override
public void log(@NotNull Throwable throwable) {
}
@Override
public void log(@NotNull String s) {
}
};
⚠️ NOTE: this is for debugging purposes only.
You can attach a VerifaiLogger
to the Verifai Core module to read the log
output from all the different Verifai modules.
Feature configuration options
Verifai contains multiple configuration options. The options can fit Verifai in any use-case. The navigation through the SDK screens differ when using different options.
The configuration can be set by calling Verifai.configure(..)
between setting the licence and starting Verifai.
Verifai.setLicence(licenceString)
// Config starts here
val config = VerifaiConfiguration(
enable_automatic = true,
require_document_copy = true,
enable_post_cropping = true,
enable_manual = true,
enable_auto_updated = true,
require_mrz_contents = true,
require_nfc_when_available = true,
read_mrz_contents = true
)
Verifai.configure(config)
// Configuration ends here
Verifai.start(....)
Verifai.setLicence(licenceString)
VerifaiConfiguration configuration = new VerifaiConfiguration();
configuration.setScanDuration(5.0);
Verifai.configure(configuration);
// Config ends here
Verifai.start(....)
Configuration parameter name | What is does | Object type | Default value |
---|---|---|---|
enable_automatic |
determines if we use the “route 1” or classifier | Boolean | true |
require_document_copy |
if set to false it switches off all AI mode screens and picture correction screens. Also skips taking a picture of the non-MRZ side. | Boolean | true |
enable_post_cropping |
The user can manually adjust the proposed document crop when set to true. | Boolean | true |
enable_manual_masking |
The user can only scan documents that are know in Verifai's databases. | Boolean | true |
enable_auto_updated |
Verifai does check for updates on its artificial intelligence models and updates when available. This improves Verifai overtime. | Boolean | true |
require_mrz_contents |
Boolean | true | |
show_instruction_screens |
Show the video instruction screens in order to guide the user through the SDK | Boolean | true |
require_nfc_when_available |
When set to true, the NfcKeyWhenAvailableValidator is added and if there are several results in the document picker that contain different chips, it should be shown. If all the same it can be skipped. |
Boolean | false |
read_mrz_contents |
if set true the whole MRZ will be read, if false it only reads the prefix | Boolean | true |
scanDuration |
Double | 5.0 | |
extraValidators |
A list of validators. Please check the paragraph called "validators" | List<VerifaiValidatorInterface> | emptyList() |
is_scan_help_enabled |
Show a hint when the user seems stuck scanning in order to show extra information | Boolean | True |
required_crop_enabled |
Crops the photos when enabled, returns the entire photos when disabled | Boolean | True |
Validators
Validators can take the Verifai SDK onto a whole new level of customization. Enhancing the general configuration options to create the perfect fit for your use case. Validators can for example black- or whitelist certain countries, exclude document types, allow only document with certain zones etcetera, etcetera.
Verifai comes with a couple of standard validators.
Validator class | Purpose |
---|---|
VerifaiDocumentCountryBlacklistValidator | Make documents from certain countries unavailable |
VerifaiDocumentCountryWhitelistValidator | Make only the documents of the countries on the list available. |
VerifaiDocumentHasMrzValidator | Only allows documents with a Machine Readable Zone (MRZ) to be scanned. |
VerifaiDocumentIsDrivingLicenceValidator | Only allows driving licences to be scanned. |
VerifaiDocumentIsTravelDocumentValidator | Only allows travel documents to be scanned. These are passports and identity cards. |
VerifaiDocumentTypesValidator | Only allows documents from the given documentType. |
VerifaiDocumentValidatorInterface | |
VerifaiMrzAvailableValidator | |
VerifaiMrzCorrectValidator | Forces the MRZ to be correct. |
VerifaiNfcKeyRequiredValidator | |
VerifaiRequireNfcWhenAvailableValidator | Required the NFC key to be correct when the document contains a supported NFC-chip. |
Filters
It is possible to filter countries or documents out of the document pickers throughout the apps. The documents cannot be selected when filtered out, but the user can proceed when an other document has been scanned.
Filter class | Purpose |
---|---|
VerifaiDocumentBlackListFilter | Hides all documents from the given countries |
VerifaiDocumentWhiteListFilter | Only shows the documents from the given countries |
VerifaiDocumentTypeWhiteListfilter | Only shows specific document types |
Errors
What follows is an overview of the errors Verifai can return with a description of what causes them.
Core Errors - Possible in all Verifai modules
Error | Type | Description | Possible solutions |
---|---|---|---|
LicenceNotValidException |
FatalException |
The used Verifai licence is invalid. Therefore Verifai can not be run. | Retrieve a new licence from https://dashboard.verifai.com |
DownloadException |
`` | Something went wrong downloading one of neural networks | Make sure an internet connection is active and retry |
NotEnoughMemoryException |
`` | The device is out of memory. | Please retry. |
FatalException |
`` | A general fatal exception | Try again, please contact Verifai support when stuck. |
NFC Component Specific errors
Error | Type | Description | Possible solutions |
---|---|---|---|
NfcDisabledException |
FatalException |
The device has an NFC reader but it has been disabled. | Ask the user to enable NFC. |
NfcException |
`` | General exception | Retry. Please contact support when it keeps occurring. |
NoNfcException |
`` | Device has no NFC reader | Skip NFC. |
Liveness Component Specific errors
Error | Type | Description | Possible solutions |
---|---|---|---|
CameraException |
FatalException |
The device has an NFC chip but it has been disabled. | Ask the user to enable NFC. |
CameraPermissionException |
`` | General camera issue exception | Retry. Please contact support when it keeps occurring. |
InvalidLivenessCheckException |
`` | Device has no NFC chip | Skip NFC. |
LivenessChecksNotAvailableException |
`` | Liveness Checks not available. Google Play services and Android 5.0 or newer are required. | Skip Liveness checks. |
RecordPermissionException |
`` | Record permission not granted | Ask for audio recording permissions. |
TimeoutException |
`` | User did not finish one of the checks on time | Let the user retry or continue, depending on your use case. |
NFC Component
The Verifai NFC module adds extra steps to your Verifai setup. The NFC modules lets the user scan and verify ICAO compliant ID cards and passports and electronic dutch drivers licences. Verifai's NFC process can be found in a separate package and can be installed via Gradle.
implementation 'com.verifai:nfc:4.4.0'
The NFC module is only available for hardware containing a NFC-chip. Please perform the following steps to make your Verifai setup compatible with the Verfai NFC module.
Check if the hardware has NFC enabled and if the result that has been obtained from the core module has support for NFC.
VerifaiNfc.isCapable(context) && result?.document?.nfcType != null && result.mrzData?.isNfcKeyValid == true
VerifaiNfc.isCapable(context) && result.document != null && result.document.nfcType != null && result.mrzData != null && result.mrzData.isNfcKeyValid != null && result.mrzData.isNfcKeyValid
The reading can begin after a positive check. This can be done by piping the
VerifaiResult
object, the one that has been obtained from the core module's listener, to the NFC module.
val nfcListener = object : VerifaiNfcResultListener {
override fun onResult(result: VerifaiNfcResult) {
// Handle the NFC result.
}
override fun onCanceled() {
// The user canceled the NFC flow
}
override fun onError(e: Throwable) {
// Something went wrong.
}
}
VerifaiNfc.start(context, it, true, nfcListener)
VerifaiNfcResultListener nfcResultListener = new VerifaiNfcResultListener() {
@Override
public void onResult(@NotNull VerifaiNfcResult verifaiNfcResult) {
// Handle the NFC result.
}
@Override void onCanceled() {
// The user canceled the NFC flow
}
@Override
public void onError(@NotNull Throwable throwable) {
// Something went wrong.
}
};
VerifaiNfc.start(context, result, true, nfcResultListener);
And done. The contents of the VerifaiNfcResult
object can be found in the general docs, since these are the same on all Verifai NFC compatible platforms.
Not all documents contain a NFC-chip or are not supported by this version of Verifai (yet). The Verifai team keeps working on covering as much travel and identification documents as possible. Please contact us if you have any documents that do not work.
Liveness Check Component
The Liveness Check uses machine learning to determine the pose of the human that is holding the device. This by analyzing the video stream that it retrieves the front camera of the device.
Please add the Liveness Check dependency to you project's build.gradle
file by adding the following line:
implementation 'com.verifai:liveness-check:4.4.0'
Not all devices can run the Liveness Check. The following prerequisites are needed:
- The device is running Android 5.0 or newer
- Google Play Services
- The device has a front facing (selfie) camera
Please check if the user can run the Liveness check before starting it. This can be done by running the following check:
if(VerifaiLiveness.isLivenessCheckSupported(context)) {
// Liveness check is supported
} else {
// Sorry, the Liveness check is not supported by this device
}
if(VerifaiLiveness.isLivenessCheckSupported(context)) {
// Liveness check is supported
} else {
// Sorry, the Liveness check is not supported by this device
}
When supported, the Liveness Check can be started by implementing the following method:
val showSkipButton = true
VerifaiLiveness.start(context, null, object : VerifaiLivenessCheckListener {
override fun onResult(result: VerifaiLivenessCheckResult) {
// Handle the result.
}
override fun onError(e: Throwable) {
// An error occurred. Sorry about that.
}
}, showSkipButton)
boolean showSkipButton = true
VerifaiLivenessCheckListener livenessResultListener = new VerifaiLivenessCheckListener() {
@Override
public void onResult(@NotNull VerifaiLivenessCheckResults verifaiLivenessCheckResults) {
// Handle the result.
}
@Override
public void onError(@NotNull Throwable throwable) {
// An error occurred. Sorry about that.
}
};
VerifaiLiveness.start(this, null, livenessResultListener, showSkipButton);
It is possible to show or hide the skipButton. This to prevent the user from skipping a certain check. There is however one risk that the user gets stuck when the facial recognition doesn't recognise the user because it is for example to dark our the user is wearing glasses or accessories. The default value for the skip button is true, so it will be shown when not set. The skip button variable is optional.
Result
The results are the same across Verifai compatible platforms. Please consult the general documentation.
Permissions
Verifai always tries to keep the number of permissions to a minimum. Some modules need extra permission checks. The Verifai Liveness module needs an extra permission to run.
Microphone
The user is asked to perform certain physical actions. These can vary from rotating the head to say certain words. All these actions are recorded and rendered into an .mp4
movie. This movie contains the frames contained from the camera and the sound that has been obtained from the user's microphone. The microphone is not needed in other modules and therefore only included in the Liveness module.
Please add the following permission to your manifest file.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Manual Data Crosscheck Component
Please add the Manual Data Crosscheck dependency to you project's build.gradle
file by adding the following line:
implementation 'com.verifai:manual-data-crosscheck:4.4.0'
Add the following code to your project. The Manual Data Crosscheck needs the result of a document scan. It can also match the picture obtained from Verifai's NFC-module when needed.
VerifaiManualDataCrossCheck.start(this, theResultObtainedFromTheDocumentScanning, object : VerifaiManualDataCrossCheckListener {
override fun onResult(result: VerifaiManualDataCrossCheckResult) {
// This is where you get the result.
}
override fun onCanceled() {
}
override fun onError(e: Throwable) {
// Something went wrong, sorry about that. Please contact support when this keeps occuring.
}
})
Result
Please consult the general documentation since the results are the same on iOS and Android.
Manual Security Data Check Component
Please add the Manual Data Crosscheck dependency to you project's build.gradle
file by adding the following line:
implementation 'com.verifai:manual-security-features-check:4.4.0'
Add the following code to your project. The Manual Security Data Check needs the result of a document scan.
VerifaiManualSecurityFeaturesCheck.start(this, MainActivity.verifaiResult!!, object : VerifaiManualSecurityFeaturesCheckListener {
override fun onResult(result: VerifaiManualSecurityFeaturesResult) {
// This is where you get the result.
}
override fun onCanceled() {
}
override fun onError(e: Throwable) {
// Something went wrong, sorry about that. Please contact support when this keeps occurring.
}
})
Result
Please consult the general documentation since the results are the same on iOS and Android.