Skip to main content

Android MRZ Scanner UI Components - SDK Features

Introduction

The Scanbot SDK provides the ability to find and extract Machine Readable Zone (MRZ) content from ID cards, passports and travel documents.

Depending on the type of document, the following fields can be extracted:

  • birth date
  • check digit birth date
  • check digit document number
  • check digit expiry date
  • check digit general
  • check digit personal number
  • date of issuance
  • document number
  • document type code
  • expiry date
  • gender
  • given names
  • issuing authority
  • language code
  • nationality
  • office of issuance
  • optional 1
  • optional 2
  • pin code
  • personal number
  • surname
  • travel doc type
  • travel doc type variant
  • version number

The MRZ scanner is available both as an RTU UI and as a classic component (types of components are explained here).

Integration

Take a look at our Example Apps to see how to integrate the MRZ scanner.

Add Feature as a Dependency

MRZScanner is available with SDK Package 2 (Data Capture Modules). You have to add the following dependency for it:

implementation("io.scanbot:sdk-package-2:$latestVersion")
implementation("io.scanbot:sdk-mrz-assets:$latestSdkVersion")
caution

Please do not use multiple scanners at the same time. For example, do not combine generic document scanner, health insurance scanner, text data scanner, etc. at the same time! Each scanner instance requires a lot of memory, GPU, and processor resources. Using multiple scanners will lead to performance issues for the entire application.

Initialize the SDK

The Scanbot SDK must be initialized before use. Add the following code snippet to your Application class:

import io.scanbot.sdk.ScanbotSDKInitializer

...

ScanbotSDKInitializer()
...
.initialize(this)
caution

Unfortunately, we have noticed that all devices using a Cortex A53 processor DO NOT SUPPORT GPU acceleration. If you encounter any problems, please disable GPU acceleration for these devices.

ScanbotSDKInitializer()
.allowGpuAcceleration(false)

Ready-To-Use UI Component

Ready-To-Use UI Component (activity) that is responsible for scanning an MRZ is MRZScannerActivity.

alt text

Have a look at our end-to-end working example of the RTU components usage here.

Starting and configuring RTU MRZ scanner

First of all, you have to add the SDK package and feature dependencies as described here.

Initialize the SDK as described here. More information about the SDK license initialization can be found here.

To use any of the RTU UI components you need to include the corresponding dependency in your build.gradle file:

implementation("io.scanbot:sdk-package-ui:$scanbotSdkVersion")

Get the latest $scanbotSdkVersion from the Changelog.

To start the RTU MRZ scanner you only have to start a new activity and be ready to process its result later.

info

Starting from version 1.90.0, the SDK RTU components contain predefined AndroidX Result API contracts. They handle part of the boilerplate for starting the RTU activity component and mapping the result once it finishes.

If your code is bundled with Android's deprecated startActivityForResult API - check the other approach we offer for this case.

val mrzResult: ActivityResultLauncher<MRZScannerConfiguration>

...

mrzResult = registerForActivityResult(MRZScannerActivity.ResultContract()) { resultEntity: MRZScannerActivity.Result ->
if (resultEntity.resultOk) {
Toast.makeText(this@MainActivity, formatResult(resultEntity.result), Toast.LENGTH_LONG).show()
}
}

...

myButton.setOnClickListener {
val mrzCameraConfiguration = MRZScannerConfiguration()
mrzResult.launch(mrzCameraConfiguration)
}
info

We offer some syntactic sugar for handling the result from RTU components via AndroidX Result API:

  • every RTU component's activity contains a Result class which, in turn, along with the resultCode value exposes a Boolean resultOk property. This will be true if resultCode equals Activity.RESULT_OK;

  • when you only expect Activity.RESULT_OK result code - you can use the AppCompatActivity.registerForActivityResultOk extension method instead of registerForActivityResult - it will be triggered only when there is a non-nullable result entity present.

caution

Always use the corresponding activity's static newIntent method to create intent when starting the RTU UI activity using deprecated startActivityForResult approach. Creating android.content.Intent object using its constructor (passing the activity's class as a parameter) will lead to the RTU UI component malfunctioning.

An instance of MRZScannerConfiguration is required for starting the RTU UI activity. It allows configuration changes through methods it exposes:

val mrzCameraConfiguration = MRZScannerConfiguration()
mrzCameraConfiguration.setFinderAspectRatio(FinderAspectRatio(8.0, 4.0))
mrzCameraConfiguration.setCancelButtonTitle("Stop")
mrzCameraConfiguration.setSuccessBeepEnabled(false)
mrzCameraConfiguration.setFinderTextHint("Place the card in scanning rectangle")
info

All parameters in MRZScannerConfiguration are optional.

Full API references for these methods can be found on this page.

Handling the result

All detected fields will be returned in the document: GenericDocument field in MRZGenericDocument instance as fields: List<Field> list. Each Field instance has next fields:

  • type: Type - the type of the field.

  • value: OcrResult? - optional value of the field. Applicable only to text fields.

  • image: Bitmap? - image crop of the field.

  • validationStatus: ValidationStatus? - field validation status. Applicable only to fields that support some kind of validation.

  • Below is a simple example of presenting the result: MRZGenericDocument fields separated by a newline character, shown in a Toast notification.

val mrzString = mrzGenericDocument?.document?.fields?.joinToString("\n") { "${it.type.name}: ${it.value?.text}" } ?: ""
Toast.makeText(this@MainActivity, mrzString, Toast.LENGTH_LONG).show()

It is also possible to use the GenericDocumentWrapper successors to use strongly typed objects and conveniently get access to the fields of the corresponding document.

To receive an instance of the scanned document wrapper, use GenericDocumentLibrary or wrap() extension function as follows:

import io.scanbot.genericdocument.entity.GenericDocumentLibrary.wrap
import io.scanbot.genericdocument.entity.MRZ
...
val mrzScanningResult = mrzGenericDocument?.document?.wrap() as MRZ
val givenName: String = mrzScanningResult.givenNames.value.text
val birthDate: String = mrzScanningResult.birthDate.value.text
val expiryDate: String? = mrzScanningResult.expiryDate?.value?.text
...

Full API references for the result class are available here.

Classic component

To integrate the classic component of the MRZ reader you can have a look at our MRZ Scanner Example Apps or check the following step-by-step integration instructions.

MRZScanner can be used in conjunction with ScanbotCameraXView or separately. Let's have a look at an example with ScanbotCameraXView.

Add feature dependencies and initialize the SDK

First of all, you have to add the SDK package and feature dependencies as described here.

Initialize the SDK as described here. More information about the SDK license initialization can be found here.

Add ScanbotCameraXView to layout

<io.scanbot.sdk.ui.camera.ScanbotCameraXView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Get MRZScanner instance from ScanbotSDK and attach it to ScanbotCameraXView

val scanbotSDK = ScanbotSDK(this)
val mrzScanner: MRZScanner = scanbotSDK.createMrzScanner()
val mrzScannerFrameHandler: MRZScannerFrameHandler = MRZScannerFrameHandler.attach(cameraView, mrzScanner)

Add a result handler for MRZScannerFrameHandler

mrzScannerFrameHandler.addResultHandler { result ->
when (result) {
is FrameHandlerResult.Success -> {
if (result.value.recognitionSuccessful) {
// do something with result here
}
}
is FrameHandlerResult.Failure -> {
// handle license error here
}
}
false
}

Method handle(FrameHandlerResult<? extends MRZGenericDocument, ? extends SdkLicenseError> result) will be triggered every time MRZScanner detects an MRZ area in the camera preview frame or if a license error has occurred.

When an MRZ area is detected you will get an MRZGenericDocument object as the result which contains all extracted data fields like documentNumber, givenNames, birthDate, etc.

You can now run your app and should see a simple camera preview that can scan MRZ data from your document.

Add a Finder Overlay

In addition, it is recommended to add a "Finder Overlay". This feature allows you to predefine an MRZ area over the ScanbotCameraXView screen. By using this overlay the MRZ scanner can skip the time-consuming step "Search for MRZ area" and perform the recognition directly in the specified "Finder Overlay" area. By using this approach the MRZ scanner recognizes and extracts the MRZ content much faster.

Details about applying finder view logic in the layout and in the code can be found here.

Want to scan longer than one minute?

Generate a free trial license to test the Scanbot SDK thoroughly.

Get your free Trial License

What do you think of this documentation?