SDK for Android 

Introduction 

The IDEMIA Verify SDK for Android provides customers with the resources to customize the SDK to their preferred user-experience and integrate it within an existing mobile application. The IDEMIA Mobile ID Verify App works in conjunction with the IDEMIA Mobile ID App allowing verifiers to authenticate the user's physical ID or digital credential (i.e., drivers license or identity card).

You can use the SDK to:

  • **Create and design your preferred user-experience and UI while leveraging the IDEMIA Verify functionalities **

    You can build a custom mobile application that implements your user-experience design and leverages all of the SDK functionalities allowing you to apply your branding and preferred user flow. You maintain complete control over the display and functionality of the application.

  • **Embed IDEMIA Verify into an existing application **

    You can automatically integrate an existing mobile application with IDEMIA by adding the SDK frameworks, which removes the need to use and maintain an additional application to leverage the Mobile ID's functionalities.


Get started 

Skills required 

Integration may be performed on Windows, Linux, or macOS.

  • Android Studio

  • Java/Kotlin for Android

  • Android operating system

Resources required 

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

  • 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)

Other requirements 

Tech
Description
Development environmentAndroid Studio 4.0+, Windows, macOS or Linux, JDK 8.. JDK12
Programming languageKotlin 1.3.71, Java 8... 12
Run timeAndroid 5.0 (API 21) or greater
PDF417 scanning SDKMicroblink 7.1.0
QR code scanning SDKMicroblink 7.1.0
Optical scanning (biomentric template)Biometric Capture SDK 4.23.1
License (LKMS)Required for Optical Inspection BioTemplate authentication

Components 

The SDK is made up of the following components:

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

SDK Core APIs

  • version snippet:

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

    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?>)
  • initDeviceEngagement snippet:

    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 snippet:

    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 snippet:

    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 snippet:

    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?>)

User permissions 

When designing your app, consider that your Android app must handle user permissions to protect the resources on the target mobile device. You must verify that the user grants the following permissions to the app:

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

The user must grants access when using an Android version higher than 2.3 (Android 6.0 Marshmallow). The SDK will throw an exception or error if the required permissions are not granted.


Create your own app 

Follow these steps to integrate the SDK.

Step 1: Add the SDK libraries 

To create your own app, you must add the SDK libraries to your project. There are two ways of doing this.

Option A: Import SDK as .aar

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

  2. Gradle sync and build.

  3. Add the following line in the app/build.gradle as shown in the snippet:

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

Option B: Import SDK from Artifactory

  1. Add the following configs in gradle.properties as shown in the snippet:

    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 as shown in the snippet:

    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='2.0.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 following dependency in app/build.gradle as shown in the snippet:

    Groovy
    1dependencies {
    2 ....
    3 implementation ("com.idemia.idverify.android:${project.ext.sdkVersionName}:${project.ext.sdkVersionCode}@aar") {
    4 transitive = true
    5 }
    6}
  4. You must include the supporting dependencies in app/build.gradle for the Verify App to work, as shown in the snippet:

    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. Include additional dependencies for the Optical Inspection feature (if used) as shown in the snippet:

    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. Gradle sync and build.

  7. 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" />

Step 2: Integrate QR code and BLE mode 

  1. Initialize the SDK configurations by calling Configs.Builder().build() in your activity/fragment.

  2. Create the SDK client object to call the SDK APIs as shown in the snippet:

    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)

    Notes:

    • 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 one time only, 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 is 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 the file, as shown in the snippet:

      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()

      Note: The above is useful in scenarios when logcat strips some logs because they are too big, for example, if response HEX with user image becomes too big to print in logcat.

    • Enabling debug in the production app may adversely affect the communication speed and overall performance of the Verify SDK for Android. One simple way to do this is to use BuildConfig.DEBUG in place of using explicitly using true or false, as shown in the snippet:

      Kotlin
      1enableDebug(BuildConfig.DEBUG)
  3. Obtain a LKMS license for your app from our support team. You can skip this step if you do not intend to use the Optical Inspection feature of the Verify App.

  4. Call the desired SDK API by supplying the necessary apiconfigs/request parameters and using 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 Mobile ID App and display the results on the Verify App screen:

    • 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 as shown in the snippet:

      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 }
    • Create the response callback for parsing engagement QR code data or PDF417 as shown in the snippet:

      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 Mobile ID App to get the credential details. The sendRequest() method will return the response from the user's Mobile ID App. If you've received it successfully, then you can display all the attributes of the Mobile ID App response in your own result activity, as shown in the snippet:

    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 as shown in the snippet:

    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 any time if an error occurs in the app, or if the user cancels the transaction by tapping the Back button. Cancel a transaction by calling the cancelTransaction() method as shown in the snippet:

    Kotlin
    1mSdkClient.cancelTransaction()

Request parameters 

The following table provides a list of attributes that can be called using the sendRequest API.

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 

QR code

Below are the QR code results from the sendRequest API with the expected data type.

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"

PDF417 scan

Below are the expected results for the PDF417 scan with the sample values and data types.

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"

Optical inspection

Below are the expected results for Optical Inspection with the sample values and data types.

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"

Deprecations and deletions 

APIs/Methods/Properties can be deprecated and may be deleted in later versions.


ProGuard rules 

The following code snippets should be added in the app ProGuard Rules file.

  • SDK obfuscation rules:

    Language not specified
    1-keep public class idemia.verify.sdk.** {
    2 public protected *;
    3}
  • Additional rules to add if BioSDK/LKMS is used:

    Language not specified
    1-keep class idemia.verify.sdk.biosdk.** { *; }
    2-keep class com.morpho.mph_bio_sdk.** { *; }
    3-keep class com.morpho.lkms.android.** {*;}
    4-keep interface morpho.sdk.** {*;}
    5-keep class net.sqlcipher.** {*;}
  • Keep everything in this package from being removed or renamed:

    Language not specified
    1*-keep class morpho.urt.msc.models.** { *; }*
  • Keep everything in this package from being removed or renamed:

    Language not specified
    1-keep class com.morpho.rt.** { *; }
    2-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.


Additions and updates 

The additions and updates to the latest SDK version are listed below:

  • DeviceAuthentication with ECDSA /signature support (based on ISO 18013-5) is shown in the snippet:

    Kotlin
    1val authentication=responseModel?.verificationStatus() as? DLAuthStatus
    2 val deviceAuthCheck:Collection<MSOAuth> = authentication.hmacStatusAll()
    3 deviceAuthCheck.forEach {
    4 // access the details of MSOAuth for each docType
    5 println(it.hmacCheck)
    6 println(it.signatureCheck)
    7 println(it.docType)
    8 //returns overall status for docType (true if any one of hmacCheck or signatureCheck is true)
    9 println(it.status)
    10 }
  • Issuer Signed Data (MSO) validity timestamp check (based on validityInfo in ISO18013-5#N1818) is shown in the snippet:

    Kotlin
    1val authentication=responseModel?.verificationStatus() as? DLAuthStatus
    2 val issuerSignatureAuth=authentication?.deviceSignedAuthStatus() //checks mso signature verification for all docTypes and returns a boolean
    3 val issuerValiditityAuth=authentication?.isValidMsoTimestamp() //checks mso signature verification for all docTypes and returns a boolean
    4
    5 // OR get full list of MSOAuth object for each docType
    6 val msoAuth:Collection<MSOAuth> = authentication.msoStatusAll()
    7 msoAuth.forEach {
    8 // access the details of MSOAuth for each docType
    9 println(it.isValidTimestamp)
    10 println(it.msoSignatureStatus)
    11 println(it.docType)
    12 }
  • isOfficial Indicates whether the vendor certificate is valid for production use.

    The isOfficial flag is calculated based on a prefix/suffix tag specified (i.e., the cert file is tagged manually by the filename suffix("prod") based on certificate information received from the vendor), as shown in the snippet:

    Kotlin
    1val isCertOfficial=responseModel.isOfficial()

Error codes 

This table lists the data error codes, messages, descriptions, and actions required.

Error Code
Error Code Message
Description
Action Required
101Invalid QR CodeUnable to scan the QR codePlease try again.
102QR Data item is missing or found any issueQR Data IssueUnable 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 codeUnable to parse the QR code that the Mobile ID has provided
104QR code scan errorInability to Scan QR code may be because of invalid data or bad encodingUnable to scan the QR code
105Error PDF417 decoderError in generating PDF417 barcodeNone
106Parsing ErrorError in compact mode qr code parsing and verificationNone
107Image Conversion ErrorError in convert image from bitmap to ImageNone
108License Validation for Optical Inspection FailedPlease try again with stable internet connectionTry Again
109License expiredPlease contact support to renew the licenseNone
121Error in security verificationVerifyID could not validate one or more security checks on response received from Mobile ID AppNone
122Generic ErrorGeneric Error from VerifyID abstraction layer; Concrete class must override to throw actual errorNone
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.Mobile ID reader is not able to get BLE, and may abort the transaction
203BLE Scanning ErrorScanning of the BLE devices failedMobile ID reader is not able to scan BLE devices, and may abort the transaction.
204Bluetooth is OFFThis device's Bluetooth is offBluetooth of the device is not enabled; Mobile ID reader may abort the transaction
205BLE Scanning ErrorProvide the BLUETOOTH permissionsNone
206BLE Scanning ErrorEnable Bluetooth to get scan resultsNone
207BLE Scanning ErrorPlease provide the BLUETOOTH_ADMIN permissionsNone
208BLE Connection TimeoutUnable to create BLE communication channel with Mobile ID deviceBLE connection failure; Mobile ID reader may abort the transaction
209BLE Scanning ErrorProvide ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission in manifest to get scan resultsNone
210BLE Scanning ErrorProvide ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission at runtime to get scan resultsNone
211Connection mode not availableVerify SDK is not able to setup connection with the Mobile ID App back-end using the configured connection type/modeNone
301Connection LostError occurred while transferring the dataMobile ID reader is not able to maintain the connection with the device, and may abort the transaction
302Error Creating RequestUnable to create the request for the mID credentialMobile ID reader is not able to create the request, and may abort the transaction
303Transaction CancelledThe transaction has been cancelled by the userUnable to scan the QR code
304Connection FailedUnable to connect the deviceBLE connection failure; Mobile ID reader may abort the transaction
305Device DisconnectedDevice has disconnected; it might not be in the range of BLEMobile ID reader may abort the transaction
306Timed Out; Try againBLE connection failure; Mobile ID reader may abort the transaction
307Request IncompleteSelect one or more attributes to be included in the request to the Mobile ID AppNone
308Incomplete RequestA Mobile ID App request comes to an end of data when expecting more data (e.g., a Mobile ID credential expects a certain length, number of arrays elements, or map entries but instead encounters the end of the data, and 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; Mobile ID reader may abort the transaction
309Request RejectedMobile ID back-end indicates that the request is rejectedNone
310Mobile ID reader authentication errorMobile ID back-end indicates there is an error with Mobile ID reader authenticationNone
311General ErrorMobile ID back-end returns an error without any given reasonMobile ID reader may inspect the request, ensure request is complete, and resend it; Mobile ID reader may abort transaction
400Error in response data receivedResponse data is malformed or nil
401Parsing ErrorMobile ID credential request encountered a data element that is not well-formed (e.g., invalid initial=byte) and failed decoding the data; Mobile ID App back-end does not return any data but the error messageMobile ID reader may inspect the request, ensure request is complete, and resend it; Mobile ID reader may abort the transaction
402Invalid FormatThe Mobile ID back-end cannot process the requested data element due to a formatting errorNone
403Data Not FoundRequested NameSpace or data element within a NameSpace is not found.None
404Data Request DeniedRelease of requested data element was rejected by Mobile ID credential holderNone
405Data Not ReturnedMobile ID back-end does not provide the requested data element, without any given reasonNone

Test samples 

Optical inspection sample 

The following screen shows the optical inspection feature with the portrait and QR code.

PDF417 sample 

The following screen shows a PDF417 scan from the Mobile ID App or a physical driver's license.

QR + BLE sample 

The following screen shows a scan of the QR code in the Mobile ID App.

Note: This 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.