Developer's Guide for Android 

The IDEMIA Verify SDK - Android v1.4.1 is targeted at developers who want to integrate the ability to verify a Mobile ID credential (mID), also known as, a mobile driver's license (mDL) in an existing mobile app.

Prerequisites 

Skills required 

The integration tasks should be done by developers with knowledge of:

  • Android Studio

  • Java/Kotlin for Android

  • Android operating system

Resources required 

Integrations may be performed on PC Windows, Linux, or Macintosh.

The tools required are:

  • Android Studio 4 or above

  • Android SDK tools: preferred latest version (release 24 or above)

  • JDK: preferred latest version (7 or above)

  • Android device (emulator is not supported)

  • Minimum SDK version is 21 (Android 5.0)

Technology stack 

Tech
Description
DEVELOPMENT ENVIRONMENT:Android Studio 4.0+, Windows, Mac or Linux, JDK 8.. JDK12
PROGRAMMING LANGUAGE:Kotlin 1.3.71, Java 8... 12
RUN TIME:Android 5.0 (API 21) or greater
PDF417 SCANNING SDK:Microblink 7.1.0
QR CODE SCANNING SDK:Microblink 7.1.0
OPTICAL SCANNING (BIOMETRIC TEMPLATE):Biometric Capture SDK 4.23.1
LICENSE (LKMS):Required for Optical Inspection BioTemplate authentication

SDK APIs and methods 

The SDK is made up of following components:

IDVerifyTerminal acts as the entry point for initializing device engagement, sending the request to the Mobile ID credential holder, receiving the response, and sending the parsed model back to the calling app. It exposes the following APIs to caller/client with the help of the concrete class IDVerifyClient.

  • version

    Kotlin
    1//Use IDVerifyTerminal.version to read Verify SDK version
    2 Log.d(TAG, "SDK Version=${IDVerifyTerminal.version}")
  • parsePDF417

    Kotlin
    1/** Parse the AAMVA raw data retrieved from physical or mobile driving license
    2 * @param String: raw/text data scanned from the 2D/PDF417 Barcode
    3 * @param callback: callback to return the response model*/
    4 abstract fun parsePDF417(apiConfigs: ApiConfigs?, callback: ResponseCallback<in ResponseItem?>)
  • initDeviceEngement

    Kotlin
    1/**
    2 * Parse the device engagement data received from QR code for NFC
    3 * @param String: raw/text data scanned from QR code/Barcode etc.
    4 * @param callback: callback to return the response model
    5 * */
    6 abstract fun initDeviceEngagement(apiConfigs: ApiConfigs?, callback: ResponseCallback<in ResponseItem?>)
  • sendRequest

    Kotlin
    1/**
    2 * sends request to the IDEMIA Mobile ID App based on the use case selected by the user in IDEMIA Mobile ID Verify App
    3 * @param callback: callback to send progress and response data back to app
    4 *
    5 * 1. create a Mobile ID credential request based on the supplied use case or parameters/configs
    6 * 2. onCreate communication channel (BLE/NFC/wifiAware, etc...) as per engagement data
    7 * 3. send the request to the IDEMIA Mobile ID App on the communication channel
    8 *
    9 * Note: In the future we may also use USECASE: use case identifier required to prepare desired request data
    10 */
    11abstract fun sendRequest(apiConfigs: ApiConfigs? = ApiConfigs.Builder().build(),
    12 callback: ICallback<in ResponseItem?, in ProgressItem>)
  • cancelRequest

    Kotlin
    1/**
    2 * cancels any transaction/running session with a Mobile ID credential. Overloads to default cancellation
    3 */
    4open fun cancelRequest(): Boolean {
    5 return cancelRequest(CancellationReason.CANCELED_BY_USER)
    6}
  • generatePDF417

    Kotlin
    1/**
    2 * Rendering PDF417 barcode
    3 * @param ApiConfigs
    4 * @param ResponseCallback<in ResponseItem?>
    5 * */
    6 abstract fun generatePDF417(apiConfigs: ApiConfigs, callback: ResponseCallback<in ResponseItem?>)

Design considerations 

End-user permissions have to be handled by the integrator/app. Specifically, you will need to check that the app permissions are granted by the end-user if the Android version is higher than 23 (Android 6.0 Marshmallow). The SDK will throw an exception or error if the required permissions are not granted.

  1. Camera permission (for QR code scan)
  2. Location permission (only when BLE client mode is used)

Sample project 

To get a copy of the IDEMIA Verify Sample App – Android, please speak to your local Sales Manager.

How to create your own app 

To create your own app, you must:

  1. Add the SDK libraries to your project. There are two ways of doing this: Option A or Option B.

Option A: Import the SDK as .aar

  1. Copy the idverifysdk-1.4.1.aar into your app/libs directory.

  2. Gradle sync and build.

  3. Add the following line in app/build.gradle.

    Groovy
    1dependencies {
    2 implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
    3 ...
    4 }

Option B: Import the SDK from Artifactory

  1. Add the following configs in gradle.properties:

    Groovy
    1artifactory_remoteUrl=https://mi-artifactory.otlabs.fr/artifactory/verify-sdk-android-release
    2artifacto ry_username=<username>
    3artifactory_password=<password>
  2. Add the following dependency in your project/build.gradle:

    Groovy
    1buildscript {
    2 repositories {
    3 google()
    4 jcenter()
    5 maven {
    6 url "https://plugins.gradle.org/m2/"
    7 }
    8 maven {
    9 url "${artifactory_remoteUrl}"
    10 credentials {
    11 username = "${artifactory_user}"
    12 password = "${artifactory_password}"
    13 }
    14 }
    15 }
    16 ...
    17 }
    18 ...
    19 allprojects {
    20 repositories {
    21 ...
    22 maven { url 'https://github.com/c-rack/cbor-java' }
    23 maven {
    24 url "${artifactory_remoteUrl}"
    25 credentials {
    26 username = "${artifactory_username}"
    27 password = "${artifactory_password}"
    28 }
    29 }
    30 }
    31 project.ext{
    32 sdkVersionName='1.4.1'
    33 sdkVersionCode=xxxx //latest release version number
    34 cborLibsVersion='0.9'
    35 bouncyCastleVersion='1.60'
    36 zxingVersion='3.6.0'
    37 zxingCoreVersion='3.3.2'
    38 }
    39 }
  3. Add the following dependency in your app/build.gradle:

    Groovy
    1dependencies {
    2 ....
    3 implementation ("com.idemia.idverify.android:${project.ext.sdkVersionName}:${project.ext.sdkVersionCode}@aar") {
    4 transitive = true
    5 }
    6}
  4. The following supporting dependencies must be added in app/build.gradle for the IDEMIA Mobile ID Verify App to work.

    Groovy
    1dependencies {
    2 //additional dependencies required for idemia id.verify sdk
    3 implementation "co.nstant.in:cbor:${project.ext.cborLibsVersion}"
    4 implementation "org.bouncycastle:bcprov-jdk15on:${project.ext.bouncyCastleVersion}"
    5 implementation("com.journeyapps:zxing-android-embedded:${project.ext.zxingVersion}") { transitive = false }
    6 implementation "com.google.zxing:core:${project.ext.zxingCoreVersion}"
    7 }
  5. Add the following additional dependencies for the Optical Inspection feature (if used):

    Groovy
    1dependencies {
    2 ...
    3 //#######libs needs to be added in integrator app #####//
    4 implementation('morpho.mph_bio_sdk.android:SmartBio:4.23.1@aar') {
    5 transitive = true
    6 }
    7 implementation "com.idemia.smartsdk:plugin-face-normal:4.23.1@aar"
    8 implementation 'com.idemia.smartsdk:plugin-algorithm-f5-4-low75:4.23.1@aar'
    9 implementation 'net.zetetic:android-database-sqlcipher:3.5.9@aar'
    10 implementation 'morpho.lkms-android:lkms_core:3.0.2@aar'
    11 implementation 'morpho.lkms-android:service_provider_local:1.2.5@aar'
    12 implementation("org.bouncycastle:bcpkix-jdk15on:${project.ext.bouncyCastleVersion}")
    13 //#######libs needs to be added in integrator app #####//
    14 }
  6. For the Line Code SDK integration, please refer to the Line Code SDK Documentation.

  7. Gradle sync and build.

  8. Add the required permissions to the project:

    XML
    1<uses-permission android:name="android.permission.BLUETOOTH" />
    2<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    3<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

integrating the qr code and ble mode 

  1. Initialize the configurations of the IDEMIA Verify SDK - Android by calling Configs.Builder().build() in your activity/fragment.

  2. Create the IDEMIA Verify SDK - Android client object to call the SDK APIs:

    Kotlin
    1val license = LicenseInfo(lkmsURL,lkmsProfileIdDev,lkmsApiKeyDev) //provide a valid LKMS license details to VerifyID
    2 val config = VSDKConfigs.Builder(this)
    3 .setLicense(license) //optional; required only if you're to use Optical Inspection
    4 .build()
    5 mSdkClient = IDVerifyTerminal.getClient(config)

    Note:

    • The minimum threshold for the BioTemplate authentication score (Optical Inspection use case) is 3500 by default.

    • An internet connection is required for first-time transactions of Optical Inspection for attribute retrieval. Attributes are downloaded from the server only one time and will not be downloaded again until one or more attributes either expire or the IDEMIA Mobile ID App is reinstalled and or the data cleared.

    • By default, no logs shall be visible on logcat from the SDK. Use enableDebug(true) for debugging purposes, only if needed, and toggle it to false for production release.

    • Use DebugCallback with enableDebug to get the logs via a callback and save them in file. This is useful in scenarios when logcat strips some logs because they are too big. e.g. response HEX with end-user image becomes too big to print in logcat.

    Kotlin
    1val config = VSDKConfigs.Builder(this)
    2 .enableDebug(BuildConfig.DEBUG, object:DebugCallback{
    3 @override
    4 fun didReceiveLogs(logs: DLog){
    5 //receive logs.message, print or write to file
    6 }
    7 })
    8 ...
    9 .build()
    • Enabling debug in the production app may adversely affect the communication speed and overall performance of the IDEMIA Verify SDK - Android. One simple way to do this is to use BuildConfig.DEBUG in place of using explicitly using true or false:

      Kotlin
      1enableDebug(BuildConfig.DEBUG)
  3. Obtain a LKMS license.

    Please contact our support team to get an LKMS license for your app. You can skip this step if your app doesn't intend to use the "Optical Inspection" feature of the IDEMIA Mobile ID Verify App.

  4. Call the desired SDK API. Supply the necessary apiconfigs/request parameters and callback to receive the results.

    • mSdkClient.initDeviceEngagment(apiconfigs,callback)
    • mSdkClient.sendRequest(apiconfigs,callback)
    • mSdkClient.cancelRequest()
      //so on...
  5. Scan the QR code or PDF417 codes.

    Follow these steps to communicate with the IDEMIA Mobile ID App and display the results on the IDEMIA Mobile ID Verify App screen.

    1. Capture the scan result in your activity or in the fragment onActivityResult. After scanning the QR code the result will display in the onActivityResult of the activity or fragment.

      Kotlin
      1override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
      2 super.onActivityResult(requestCode, resultCode, data)
      3 //handle all the results
      4 if (requestCode == REQUEST_SCAN_BARCODES_MICROBLINK) {
      5 if (resultCode == Activity.RESULT_OK) {
      6 // updates bundled recognizers with results that have arrived
      7 mRecognizerBundle.loadFromIntent(data)
      8 val result = mBarcodeRecognizer.result
      9 // *ScanType= QRCode //*ScanType= PDF417
      10 Log.d(TAG, "ScanType= " + result.barcodeType.name)
      11 doHandleScannedData(result.stringData, result.barcodeType)
      12 }
      13 }
      14 }
    2. Create the response callback for parsing engagement QR code data or PDF417.

    Kotlin
    1open fun doHandleScannedData(scannedData: String?, scanType: BarcodeType? = null) {
    2 if (!scannedData.isNullOrEmpty()) {
    3 val apiConfigs = ApiConfigs.Builder()
    4 .withData(scannedData)
    5 .withImage(imageBytes or MorphoImage)//screenshot of other device with user face image + QR code
    6 .build()
    7 when (scanType) {
    8 BarcodeType.QRCode -> {
    9 mSdkClient?.initDeviceEngagement(apiConfigs, mDEParserCallback)
    10 }
    11 BarcodeType.PDF417 -> {
    12 mSdkClient?.parsePDF417(apiConfigs, m2DBarcodeParseCallback)
    13 }
    14 else -> {
    15 }
    16 }
    17 }
    18 }
    19 /** Response callback for parse engagement QR code data */
    20 private val mDEParserCallback = object : ResponseCallback<DeviceEngagementModel?> {
    21 override fun onSuccess(deviceEngegmentModel: DeviceEngagementModel?) {
    22 // deviceEngegmentModel received. perform next step
    23 doStartDataTransfer(deviceEngegmentModel)
    24 }
    25 override fun onError(error: IError?) {
    26 handleError(error)
    27 }
    28 }
    29 /**or PDF417 raw data from physical or Mobile ID credential holder*/
    30 private val m2DBarcodeParseCallback = object : ResponseCallback<DLDataModel?> {
    31 override fun onSuccess(result: DLDataModel?) {
    32 // PDF417 barcode scanning result. Display result screen
    33 displayResult(result)
    34 }
    35 override fun onError(error: IError?) {
    36 handleError(error as VSDKError)
    37 }
    38 }
  6. Send the request to the IDEMIA Mobile ID App to get the credential details. The sendRequest() method will return the response from the end-user's IDEMIA Mobile ID App. If you've received it successfully, then you can display all the attributes of the IDEMIA Mobile ID App response in your own result activity.

    Kotlin
    1private fun doStartDataTransfer(deModel: DeviceEngagementModel?) {
    2 val namespaceParamList = getRequestedParamList() // make map of namespace to List<MIDRequestParam>
    3 val apiConfigs = ApiConfigs.MIDRequestBuilder()
    4 .version("1.0")
    5 //add docType
    6 .addDocType(DOCTYPE_18013_5).apply {
    7 addParams(NAMESPACE_18013_5, isoParamList)
    8 .addParam(DOCTYPE_ORG_AAMVA_US, MIDRequestParam(REAL_ID))
    9 // pass all request params as Map<namespace->List<MIDRequest
    10 .addParams(namespaceParamList)
    11 //OR use another overload. duplicate params shall be removed if found
    12 .addParams(DOCTYPE_ORG_AAMVA_US, namespaceParamList.get(DOCTYPE_ORG_AAMVA_US)!!)
    13 .addParams(DOCTYPE_18013_5, namespaceParamList.get(DOCTYPE_18013_5)!!)
    14 //OR this way
    15 .addParams(
    16 "my.custom.namespace2", listOf(
    17 MIDRequestParam("custom_param_nm21"),
    18 MIDRequestParam("custom_param_nm22"),
    19 MIDRequestParam("custom_param_nm23"),
    20 MIDRequestParam("custom_param_nm21") //duplicate
    21 )
    22 )
    23 //OR use 3rd overload to pass params one by one
    24 .addParam("my.custom.namespace", MIDRequestParam("custom_param1"))
    25 // add requestInfo as map
    26 .addRequestInfo(
    27 infoMap = hashMapOf(
    28 "reqKey1" to "reqVal1",
    29 "reqKey2" to "reqVal2",
    30 "reqKey3" to false,
    31 "reqKey4" to 3334
    32 )
    33 )
    34 //or use other overload to add one by one
    35 .addRequestInfo("reqinfo1", "value1")
    36 .addRequestInfo("reqinfo2", "value2")
    37 .addRequestInfo("reqinfoLong", 180L)
    38 .addRequestInfo("reqinfoBool", true)
    39 .addRequestInfo("reqinfoBytArr", "sdkghdkgs".toByteArray())
    40 .addRequestInfo("reqinfoDouble", 3.7)
    41 .addRequestInfo("reqinfoFloat", 3.7F)
    42 // add as dataItem
    43 .addRequestInfo(
    44 "reqinfoDataItem",
    45 CborBuilder().addArray().add(1).add("item2").add("item3").end().build()
    46 .first()
    47 )
    48 }.buildDoc()
    49 //add another docType
    50 .addDocType("my.cusom.docType.custom").apply {
    51 addParams(
    52 "my.custom.namespace2", listOf(
    53 MIDRequestParam("custom_param_nm21", true),
    54 MIDRequestParam("custom_param_nm22"),
    55 MIDRequestParam("custom_param_nm23"),
    56 MIDRequestParam("custom_param_nm21", true) //duplicate
    57 )
    58 )
    59 // add requestInfo as map
    60 .addRequestInfo(
    61 infoMap = hashMapOf(
    62 "reqKey1" to "reqVal1",
    63 "reqKey2" to "reqVal2",
    64 "reqKey3" to false,
    65 "reqKey4" to 3334
    66 )
    67 )
    68 }.buildDoc()
    69 .build()
    70 if (deModel?.isMDLAsPeripheral()) {
    71 askLocationPermission() /* android.permission.ACCESS_COARSE_LOCATION to be added in AndroidManifest */
    72 //get permissin and then call sendRequest
    73 } else {
    74 mSdkClient?.sendRequest(apiConfigs, callback = mRequestCallback)
    75 }
    76 }
  7. Obtain the response callback for parsing the engagement QR code data or the PDF417 scan.

    Kotlin
    1/**
    2 * Request callback for sendRequest SDK api to receive and display response data from Mobile ID
    3 */
    4 val mRequestCallback = object : RequestCallback<ResponseItem?, ProgressItem> {
    5 override fun onSuccess(response: ResponseItem?) {
    6 Log.e(TAG, "Mobile ID response:$response")
    7 displayResponse(response as DLDataModel)
    8 }
    9 override fun onError(error: IError?) {
    10 handleError(error = error as VSDKError)
    11 }
    12 override fun onProgress(progress: ProgressItem) {
    13 Log.e(TAG, progress.toString())
    14 }
    15 override fun onRequestSent(status: Boolean, waitTimeMillis: Long) {
    16 super.onRequestSent(status, waitTimeMillis)
    17 }
    18 }
  8. You can cancel a transaction in between any time if any error occurs in the app or if the end-user cancels the transaction by tapping the Back button. Cancel a transaction by calling the cancelTransaction() method.

    Kotlin
    1mSdkClient.cancelTransaction()

Deprecations and deletions 

  • Deprecations in DLDataModel
  • Direct access to authStatus field deprecated. Call verificationStatus() instead.

Additions and updates 

  • Added optional method withImage in ApiConfig.Builder for initDeviceEngagement which takes the captured device screenshot image (while scanning a compact QR) for BioTemplate authentication
  • Added optional method setLicense in VSDKConfigs.Builder to supply the LKMS license detail to the IDEMIA Verify SDK - Android
  • Added model class OIDLDataModel which encapsulates the attributes list and corresponding security checks for the Optical Inspection QR code result
  • Added new model class OpticalInspectionAuth to return security checks related to the Optical Inspection process.
Kotlin
1val security=responseModel.verificationStatus() as? OpticalInspectionAuth
2 //security.isSuccess() returns true if all checks are successful

ProGuard rules 

The following rules should be added in the app ProGuard rules file:

  • sdk obfuscation rules

    -keep public class idemia.verify.sdk.*_ { public protected _; }

  • Additional rules to add if BioSDK/LKMS is used:

    -keep class idemia.verify.sdk.biosdk.** { *; } -keep class com.morpho.mph_bio_sdk.** { ; } -keep class com.morpho.lkms.android.** {;} -keep interface morpho.sdk.** {*;} -keep class net.sqlcipher.** {*;}

  • Keep everything in this package from being removed or renamed:

    -keep class morpho.urt.msc.models.*_ { _; }

  • Keep everything in this package from being removed or renamed:

    -keep class com.morpho.rt.*_ { _; }

    -keep class morpho.rt.imageconvert.*_ { _; }

  • Keep the class and specified members from being removed or renamed:

    -keep class morpho.rt.imageconvert.MorphoImageConvert_JNI { *; }

If these properties are not defined, LKMS will fail to resolve a valid license and the BioTemplate authentication will fail for the Optical Inspection use case.

Request parameters 

Item #
Identifier
Param Name
CBOR Type
1ADMINISTRATIVE_NUMBERadministrative_numberMajor type 3
2GENDERgenderMajor type 3
3HEIGHTheightMajor type 0
4WEIGHTweightMajor type 0
5EYE_COLOReye_colorMajor type 3
6HAIR_COLORhair_colorMajor type 3
7BIRTH_PLACEbirthplaceMajor type 3
8RESIDENT_ADDRESSresident_addressMajor type 3
9PORTRAIT_CAPTURE_DATEportrait_capture_dateTag value 0 of major type 6
10AGE_IN_YEARSage_in_yearsMajor type 0
11AGE_BIRTH_YEARage_birth_yearMajor type 0
12AGE_OVER_NNage_over_NNValue 20/21 of major type 7
13ISSUING_JURISDICTIONissuing_jurisdictionMajor Type 3
14NATIONALITYnationalityMajor type 3
15RESIDENT_CITYresident_cityMajor type 3
16RESIDENT_STATEresident_stateMajor type 3
17RESIDENT_POSTAL_CODEresident_postal_codeMajor type 3
18BIOMETRIC_TEMPLATE_XXbiometric_template_xxMajor type 2
19NAME_NAT_CHARname_nat_charMajor type 3
20MGMT_NEXT_UPDATEmgmt_nextupdateTag value 0 of major type 6
21FAMILY_NAMEfamily_nameMajor type 3
22GIVEN_NAMEgiven_nameTag value 0 of major type 6
23BIRTHDATEbirthdateTag value 0 of major type 6
24ISSUE_DATEissue_dateTag value 0 of major type 6
25EXPIRY_DATEexpiry_dateMajor type 3
26ISSUING_COUNTRYissuing_countryMajor type 3
27ISSUING_AUTHORITYissuing_authorityMajor type 3
28DOCUMENT_NUMBERdocument_numberMajor type 3
29PORTRAITportraitMajor type 2
30MGMT_LAST_UPDATEmgmt_lastupdateTag value 0 of major type 6
31MGMT_VALIDITYmgmt_validityTag value 0 of major type 6
32ONLINE_TOKEN_XXXXonline_token_xxxxMajor type 3
34DRIVING_PRIVILEGESdriving_privilegesMajor type 4
35REAL_IDRealIDMajor type 3 //org.aamva namespace
36SIGNATURE_USUAL_MARKsignature_usual_markMajor type 3
37ONLINE_URL_XXXXonline_url_xxxxMajor type 3
38BIRTHDATEbirth_dateMajor type 3
39BIRTH_PLACEbirth_placeMajor type 3
40NAME_NAT_CHARname_national_characterMajor type 3

Expected results 

Data Fields
Data type/Unit
Sample Value
administrative_numberText/String"1234453"
genderText/String"M"
heightInteger/Centimeter"157"
weightInteger/Kg"56"
eye_colorText/String"BLU"
hair_colorText/String"BLACK"
birthplaceText/String"NY"
resident_addressText/String"123, ABC Street"
portrait_capture_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
age_in_yearsInteger/String"34"
age_birth_yearInteger/String"1978"
age_over_NNBoolean/String"true"
issuing_jurisdictionText/String"NY"
nationalityText/String"US"
resident_cityText/String"NY"
resident_stateText/String"NY"
resident_postal_codeText/String"58773"
name_nat_charText/String"US"
mgmt_nextupdateDateTime/RFC3339"1985-04-12T23:20:50Z"
family_nameText/String"Sample"
given_nameText/String"Joe"
birthdateDateTime/RFC3339"1985-04-12T23:20:50Z"
issue_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
expiry_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
issuing_countryText/String"US"
issuing_authorityText/String"NY"
document_numberInt/String"782593823"
portraitByteArray/Bytes
mgmt_lastupdateDateTime/RFC3339"1985-04-12T23:20:50Z"
mgmt_validityDateTime/RFC3339"1985-04-12T23:20:50Z"
driving_privilegesText/String"C"
RealIDBoolean/Stringtrue
signature_usual_markByteArray/Bytes
birth_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
birth_placeText/String"NY"
name_national_characterText/String"US"

Expected results (PDF417 scan) 

Data Fields
Data type/Unit
Sample Value
genderText/String"M"
heightInteger/inches"71"
eye_colorText/String"BLU"
resident_addressText/String"123, ABC Street"
age_in_yearsInteger/String"34"
age_over_NNBoolean/String"true"
resident_cityText/String"NY"
resident_stateText/String"NY"
resident_postal_codeText/String"58773"
family_nameText/String"Sample"
birthdateDateTime/RFC3339"1985-04-12T23:20:50Z"
issue_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
expiry_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
issuing_countryText/String"USA"
document_numberInt/String"782593823"
driving_privilegesText/String"C"

Expected results (Optical Inspection) 

Data Fields
Data type/Unit
Sample Value
genderText/String"M"
family_nameText/String"Sample"
given_nameText/String"Joe"
birthdateDateTime/RFC3339"1985-04-12T23:20:50Z"
expiry_dateDateTime/RFC3339"1985-04-12T23:20:50Z"

Error codes 

Error Code
Error Code Message
Description
Action Required
101Invalid QR CodeUnable to scan the QR code.Please try again.
102QR Data item is missing or found any issueQR Data Issue.Unable to find some elements in the QR data item. The Mobile ID reader may abort the transaction.
103QR Code parsing errorUnable to parse the Mobile ID App QR code.Unable to parse the QR code that the mID has provided.
104QR code scan errorUnable to Scan QR code may be because of invalid data or bad encoding.Unable to scan the QR code.
105Error PDF417 decoderError in generating PDF417 barcode
106Parsing ErrorError in compact mode qr code parsing and verification
107Image Conversion ErrorError in convert image from bitmap to Image
108License Validation for Optical Inspection FailedPlease try again with stable internet connectionTry Again.
109License expiredPlease contact support to renew the license
121Error in security verificationVerifyID could not validate one or more security checks on response received from the IDEMIA Mobile ID App.
122Generic ErrorGeneric Error from VerifyID abstraction layer. Concrete class must override to throw actual error.
201Unable to initialize BLEError in initializing BLE feature of this device.The Mobile ID reader is not able to get BLE. The Mobile ID reader may abort the transaction.
202Device Doesn't Support BLEThis device doesn't support the BLE feature.The Mobile ID reader is not able to get BLE. The Mobile ID reader may abort the transaction.
203BLE Scanning ErrorScanning of the BLE devices failed.The Mobile ID reader is not able to scan the BLE devices. The Mobile ID reader may abort the transaction.
204Bluetooth is OFFThis device's Bluetooth is off.The Bluetooth of the device is not enabled. The Mobile ID reader may abort the transaction.
205BLE Scanning ErrorPlease provide the BLUETOOTH permissions
206BLE Scanning ErrorPlease enable Bluetooth to get scan results
207BLE Scanning ErrorPlease provide the BLUETOOTH_ADMIN permissions
208BLE Connection TimeoutUnable to create BLE communication channel with the Mobile ID device.BLE connection failure. The Mobile ID reader may abort the transaction.
209BLE Scanning ErrorPlease provide ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission in manifest to get scan results
210BLE Scanning ErrorPlease provide ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission at runtime to get scan results
211Connection mode not availableIDEMIA Verify SDK - Android is not able to setup connection with the Mobile ID App back-end using the configured connection type/mode.
301Connection LostError occurred while transferring the data.The Mobile ID reader is not able to maintain the connection with the device. The Mobile ID reader may abort the transaction.
302Error Creating RequestUnable to create the request for the mID credential.The Mobile ID reader is not able to create the request. The Mobile ID reader may abort the transaction.
303Transaction CancelledThe transaction has been cancelled by the end-user.Unable to scan the QR code.
304Connection FailedUnable to connect the device.There is a BLE connection failure. The Mobile ID reader may abort the transaction.
305Device DisconnectedThe device has disconnected. Maybe the device is not in the range of BLE.The Mobile ID reader may abort the transaction.
306Timed Out, Please try againBLE connection failure. The Mobile ID reader may abort the transaction.
307Request IncompletePlease select one or more attributes to be included in the request to the Mobile ID App.
308Incomplete RequestA Mobile ID App request comes to an end of data when expecting more data. For example, a Mobile ID credential expects a certain length, number of arrays elements, or map entries but instead encounters the end of the data. The Mobile ID App back-end does not return any data but the error messageThe Mobile ID reader may inspect the request, ensure request is complete, and resend it. The Mobile ID reader may abort the transaction.
309Request RejectedThe Mobile ID back-end indicates that the request is rejected.
310Mobile ID reader authentication errorThe Mobile ID back-end indicates there is an error with Mobile ID reader authentication.
311General ErrorThe Mobile ID back-end returns an error without any given reason.The Mobile ID reader may inspect the request, ensure request is complete, and resend it. The Mobile ID reader may abort the transaction.
400Error in response data receivedResponse data is malformed or nil
401Parsing ErrorA Mobile ID credential request encountered a data element that is not well-formed (e.g., invalid initial=byte) and failed decoding the data. The Mobile ID App back-end does not return any data but the error message.The Mobile ID reader may inspect the request, ensure request is complete, and resend it. The Mobile ID reader may abort the transaction.
402Invalid FormatThe Mobile ID back-end cannot process the requested data element due to a formatting error.
403Data Not FoundThe requested NameSpace or data element within a NameSpace is not found.
404Data Request DeniedThe release of requested data element was rejected by the Mobile ID credential holder.
405Data Not ReturnedThe Mobile ID back-end does not provide the requested data element without any given reason.

Test samples 

Line code sample 

linecode sample

Optical inspection sample 

PDF417 sample 

QR + BLE sample 

Note: The below screenshot is only for device engagement QR code testing. The full QR + BLE scenario will only work with a real device with the IDEMIA Mobile ID App installed.