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 environment | Android Studio 4.0+, Windows, macOS 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 (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 classIDVerifyClient
.
SDK Core APIs
-
version
snippet:Kotlin1//Use IDVerifyTerminal.version to read Verify SDK version2 Log.d(TAG, "SDK Version=${IDVerifyTerminal.version}") -
parsePDF417
snippet:Kotlin1/** Parse the AAMVA raw data retrieved from physical or mobile driving license2 * @param String: raw/text data scanned from the 2D/PDF417 Barcode3 * @param callback: callback to return the response model*/4 abstract fun parsePDF417(apiConfigs: ApiConfigs?, callback: ResponseCallback<in ResponseItem?>) -
initDeviceEngagement
snippet:Kotlin1/**2 * Parse the device engagement data received from QR code for NFC3 * @param String: raw/text data scanned from QR code/Barcode etc.4 * @param callback: callback to return the response model5 * */6 abstract fun initDeviceEngagement(apiConfigs: ApiConfigs?, callback: ResponseCallback<in ResponseItem?>) -
sendRequest
snippet:Kotlin1/**2 * sends request to the IDEMIA Mobile ID App based on the use case selected by the user in IDEMIA Mobile ID Verify App3 * @param callback: callback to send progress and response data back to app4 *5 * 1. create a Mobile ID credential request based on the supplied use case or parameters/configs6 * 2. onCreate communication channel (BLE/NFC/wifiAware, etc...) as per engagement data7 * 3. send the request to the IDEMIA Mobile ID App on the communication channel8 *9 * Note: In the future we may also use USECASE: use case identifier required to prepare desired request data10 */11abstract fun sendRequest(apiConfigs: ApiConfigs? = ApiConfigs.Builder().build(),12 callback: ICallback<in ResponseItem?, in ProgressItem>) -
cancelRequest
snippet:Kotlin1/**2 * cancels any transaction/running session with a Mobile ID credential. Overloads to default cancellation3 */4open fun cancelRequest(): Boolean {5 return cancelRequest(CancellationReason.CANCELED_BY_USER)6} -
generatePDF417
snippet:Kotlin1/**2 * Rendering PDF417 barcode3 * @param ApiConfigs4 * @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:
- Camera permission (for QR code scan)
- 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
-
Copy idverifysdk-2.0.1.aar into your app/libs directory.
-
Gradle sync and build.
-
Add the following line in the app/build.gradle as shown in the snippet:
Groovy1dependencies {2 implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')3 ...4 }
Option B: Import SDK from Artifactory
-
Add the following configs in gradle.properties as shown in the snippet:
Groovy1artifactory_remoteUrl=https://mi-artifactory.otlabs.fr/artifactory/verify-sdk-android-release2artifacto ry_username=<username>3artifactory_password=<password> -
Add the following dependency in your project/build.gradle as shown in the snippet:
Groovy1buildscript {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 number34 cborLibsVersion='0.9'35 bouncyCastleVersion='1.60'36 zxingVersion='3.6.0'37 zxingCoreVersion='3.3.2'38 }39 } -
Add following dependency in app/build.gradle as shown in the snippet:
Groovy1dependencies {2 ....3 implementation ("com.idemia.idverify.android:${project.ext.sdkVersionName}:${project.ext.sdkVersionCode}@aar") {4 transitive = true5 }6} -
You must include the supporting dependencies in app/build.gradle for the Verify App to work, as shown in the snippet:
Groovy1dependencies {2 //additional dependencies required for idemia id.verify sdk3 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 } -
Include additional dependencies for the Optical Inspection feature (if used) as shown in the snippet:
Groovy1dependencies {2 ...3 //#######libs needs to be added in integrator app #####//4 implementation('morpho.mph_bio_sdk.android:SmartBio:4.23.1@aar') {5 transitive = true6 }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 } -
Gradle sync and build.
-
Add the required permissions to the project:
XML1<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
-
Initialize the SDK configurations by calling
Configs.Builder().build()
in your activity/fragment. -
Create the SDK client object to call the SDK APIs as shown in the snippet:
Kotlin1val license = LicenseInfo(lkmsURL,lkmsProfileIdDev,lkmsApiKeyDev) //provide a valid LKMS license details to VerifyID2 val config = VSDKConfigs.Builder(this)3 .setLicense(license) //optional; required only if you're to use Optical Inspection4 .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 tofalse
for production release.
-
Use
DebugCallback
withenableDebug
to get the logs via a callback and save them in the file, as shown in the snippet:Kotlin1val config = VSDKConfigs.Builder(this)2 .enableDebug(BuildConfig.DEBUG, object:DebugCallback{3 @override4 fun didReceiveLogs(logs: DLog){5 //receive logs.message, print or write to file6 }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:Kotlin1enableDebug(BuildConfig.DEBUG)
-
-
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.
-
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...
-
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 theonActivityResult
of the activity or fragment as shown in the snippet:Kotlin1override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {2 super.onActivityResult(requestCode, resultCode, data)3 //handle all the results4 if (requestCode == REQUEST_SCAN_BARCODES_MICROBLINK) {5 if (resultCode == Activity.RESULT_OK) {6 // updates bundled recognizers with results that have arrived7 mRecognizerBundle.loadFromIntent(data)8 val result = mBarcodeRecognizer.result9 // *ScanType= QRCode //*ScanType= PDF41710 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:
Kotlin1open 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 code6 .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 step23 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 screen33 displayResult(result)34 }35 override fun onError(error: IError?) {36 handleError(error as VSDKError)37 }38 }
-
-
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:Kotlin1private 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 docType6 .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<MIDRequest10 .addParams(namespaceParamList)11 //OR use another overload. duplicate params shall be removed if found12 .addParams(DOCTYPE_ORG_AAMVA_US, namespaceParamList.get(DOCTYPE_ORG_AAMVA_US)!!)13 .addParams(DOCTYPE_18013_5, namespaceParamList.get(DOCTYPE_18013_5)!!)14 //OR this way15 .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") //duplicate21 )22 )23 //OR use 3rd overload to pass params one by one24 .addParam("my.custom.namespace", MIDRequestParam("custom_param1"))25 // add requestInfo as map26 .addRequestInfo(27 infoMap = hashMapOf(28 "reqKey1" to "reqVal1",29 "reqKey2" to "reqVal2",30 "reqKey3" to false,31 "reqKey4" to 333432 )33 )34 //or use other overload to add one by one35 .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 dataItem43 .addRequestInfo(44 "reqinfoDataItem",45 CborBuilder().addArray().add(1).add("item2").add("item3").end().build()46 .first()47 )48 }.buildDoc()49 //add another docType50 .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) //duplicate57 )58 )59 // add requestInfo as map60 .addRequestInfo(61 infoMap = hashMapOf(62 "reqKey1" to "reqVal1",63 "reqKey2" to "reqVal2",64 "reqKey3" to false,65 "reqKey4" to 333466 )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 sendRequest73 } else {74 mSdkClient?.sendRequest(apiConfigs, callback = mRequestCallback)75 }76 } -
Obtain the response callback for parsing the engagement QR code data or the PDF417 scan as shown in the snippet:
Kotlin1/**2 * Request callback for sendRequest SDK api to receive and display response data from Mobile ID3 */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 } -
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:Kotlin1mSdkClient.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 |
---|---|---|---|
1 | ADMINISTRATIVE_NUMBER | administrative_number | Major type 3 |
2 | GENDER | gender | Major type 3 |
3 | HEIGHT | height | Major type 0 |
4 | WEIGHT | weight | Major type 0 |
5 | EYE_COLOR | eye_color | Major type 3 |
6 | HAIR_COLOR | hair_color | Major type 3 |
7 | BIRTH_PLACE | birthplace | Major type 3 |
8 | RESIDENT_ADDRESS | resident_address | Major type 3 |
9 | PORTRAIT_CAPTURE_DATE | portrait_capture_date | Tag value 0 of major type 6 |
10 | AGE_IN_YEARS | age_in_years | Major type 0 |
11 | AGE_BIRTH_YEAR | age_birth_year | Major type 0 |
12 | AGE_OVER_NN | age_over_NN | Value 20/21 of major type 7 |
13 | ISSUING_JURISDICTION | issuing_jurisdiction | Major Type 3 |
14 | NATIONALITY | nationality | Major type 3 |
15 | RESIDENT_CITY | resident_city | Major type 3 |
16 | RESIDENT_STATE | resident_state | Major type 3 |
17 | RESIDENT_POSTAL_CODE | resident_postal_code | Major type 3 |
18 | BIOMETRIC_TEMPLATE_XX | biometric_template_xx | Major type 2 |
19 | NAME_NAT_CHAR | name_nat_char | Major type 3 |
20 | MGMT_NEXT_UPDATE | mgmt_nextupdate | Tag value 0 of major type 6 |
21 | FAMILY_NAME | family_name | Major type 3 |
22 | GIVEN_NAME | given_name | Tag value 0 of major type 6 |
23 | BIRTHDATE | birthdate | Tag value 0 of major type 6 |
24 | ISSUE_DATE | issue_date | Tag value 0 of major type 6 |
25 | EXPIRY_DATE | expiry_date | Major type 3 |
26 | ISSUING_COUNTRY | issuing_country | Major type 3 |
27 | ISSUING_AUTHORITY | issuing_authority | Major type 3 |
28 | DOCUMENT_NUMBER | document_number | Major type 3 |
29 | PORTRAIT | portrait | Major type 2 |
30 | MGMT_LAST_UPDATE | mgmt_lastupdate | Tag value 0 of major type 6 |
31 | MGMT_VALIDITY | mgmt_validity | Tag value 0 of major type 6 |
32 | ONLINE_TOKEN_XXXX | online_token_xxxx | Major type 3 |
34 | DRIVING_PRIVILEGES | driving_privileges | Major type 4 |
35 | REAL_ID | RealID | Major type 3 //org.aamva namespace |
36 | SIGNATURE_USUAL_MARK | signature_usual_mark | Major type 3 |
37 | ONLINE_URL_XXXX | online_url_xxxx | Major type 3 |
38 | BIRTHDATE | birth_date | Major type 3 |
39 | BIRTH_PLACE | birth_place | Major type 3 |
40 | NAME_NAT_CHAR | name_national_character | Major 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_number | Text/String | "1234453" |
gender | Text/String | "M" |
height | Integer/Centimeter | "157" |
weight | Integer/Kg | "56" |
eye_color | Text/String | "BLU" |
hair_color | Text/String | "BLACK" |
birthplace | Text/String | "NY" |
resident_address | Text/String | "123, ABC Street" |
portrait_capture_date | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
age_in_years | Integer/String | "34" |
age_birth_year | Integer/String | "1978" |
age_over_NN | Boolean/String | "true" |
issuing_jurisdiction | Text/String | "NY" |
nationality | Text/String | "US" |
resident_city | Text/String | "NY" |
resident_state | Text/String | "NY" |
resident_postal_code | Text/String | "58773" |
name_nat_char | Text/String | "US" |
mgmt_nextupdate | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
family_name | Text/String | "Sample" |
given_name | Text/String | "Joe" |
birthdate | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
issue_date | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
expiry_date | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
issuing_country | Text/String | "US" |
issuing_authority | Text/String | "NY" |
document_number | Int/String | "782593823" |
portrait | ByteArray/Bytes | |
mgmt_lastupdate | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
mgmt_validity | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
driving_privileges | Text/String | "C" |
RealID | Boolean/String | true |
signature_usual_mark | ByteArray/Bytes | |
birth_date | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
birth_place | Text/String | "NY" |
name_national_character | Text/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 |
---|---|---|
gender | Text/String | "M" |
height | Integer/inches | "71" |
eye_color | Text/String | "BLU" |
resident_address | Text/String | "123, ABC Street" |
age_in_years | Integer/String | "34" |
age_over_NN | Boolean/String | "true" |
resident_city | Text/String | "NY" |
resident_state | Text/String | "NY" |
resident_postal_code | Text/String | "58773" |
family_name | Text/String | "Sample" |
birthdate | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
issue_date | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
expiry_date | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
issuing_country | Text/String | "USA" |
document_number | Int/String | "782593823" |
driving_privileges | Text/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 |
---|---|---|
gender | Text/String | "M" |
family_name | Text/String | "Sample" |
given_name | Text/String | "Joe" |
birthdate | DateTime/RFC3339 | "1985-04-12T23:20:50Z" |
expiry_date | DateTime/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 specified1-keep public class idemia.verify.sdk.** {2 public protected *;3} -
Additional rules to add if BioSDK/LKMS is used:
Language not specified1-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 specified1*-keep class morpho.urt.msc.models.** { *; }* -
Keep everything in this package from being removed or renamed:
Language not specified1-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:Kotlin1val authentication=responseModel?.verificationStatus() as? DLAuthStatus2 val deviceAuthCheck:Collection<MSOAuth> = authentication.hmacStatusAll()3 deviceAuthCheck.forEach {4 // access the details of MSOAuth for each docType5 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:Kotlin1val authentication=responseModel?.verificationStatus() as? DLAuthStatus2 val issuerSignatureAuth=authentication?.deviceSignedAuthStatus() //checks mso signature verification for all docTypes and returns a boolean3 val issuerValiditityAuth=authentication?.isValidMsoTimestamp() //checks mso signature verification for all docTypes and returns a boolean45 // OR get full list of MSOAuth object for each docType6 val msoAuth:Collection<MSOAuth> = authentication.msoStatusAll()7 msoAuth.forEach {8 // access the details of MSOAuth for each docType9 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:Kotlin1val 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 |
---|---|---|---|
101 | Invalid QR Code | Unable to scan the QR code | Please try again. |
102 | QR Data item is missing or found any issue | QR Data Issue | Unable to find some elements in the QR data item; the Mobile ID reader may abort the transaction |
103 | QR Code parsing error | Unable to parse the Mobile ID App QR code | Unable to parse the QR code that the Mobile ID has provided |
104 | QR code scan error | Inability to Scan QR code may be because of invalid data or bad encoding | Unable to scan the QR code |
105 | Error PDF417 decoder | Error in generating PDF417 barcode | None |
106 | Parsing Error | Error in compact mode qr code parsing and verification | None |
107 | Image Conversion Error | Error in convert image from bitmap to Image | None |
108 | License Validation for Optical Inspection Failed | Please try again with stable internet connection | Try Again |
109 | License expired | Please contact support to renew the license | None |
121 | Error in security verification | VerifyID could not validate one or more security checks on response received from Mobile ID App | None |
122 | Generic Error | Generic Error from VerifyID abstraction layer; Concrete class must override to throw actual error | None |
201 | Unable to initialize BLE | Error 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. |
202 | Device Doesn't Support BLE | This device doesn't support the BLE feature. | Mobile ID reader is not able to get BLE, and may abort the transaction |
203 | BLE Scanning Error | Scanning of the BLE devices failed | Mobile ID reader is not able to scan BLE devices, and may abort the transaction. |
204 | Bluetooth is OFF | This device's Bluetooth is off | Bluetooth of the device is not enabled; Mobile ID reader may abort the transaction |
205 | BLE Scanning Error | Provide the BLUETOOTH permissions | None |
206 | BLE Scanning Error | Enable Bluetooth to get scan results | None |
207 | BLE Scanning Error | Please provide the BLUETOOTH_ADMIN permissions | None |
208 | BLE Connection Timeout | Unable to create BLE communication channel with Mobile ID device | BLE connection failure; Mobile ID reader may abort the transaction |
209 | BLE Scanning Error | Provide ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission in manifest to get scan results | None |
210 | BLE Scanning Error | Provide ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission at runtime to get scan results | None |
211 | Connection mode not available | Verify SDK is not able to setup connection with the Mobile ID App back-end using the configured connection type/mode | None |
301 | Connection Lost | Error occurred while transferring the data | Mobile ID reader is not able to maintain the connection with the device, and may abort the transaction |
302 | Error Creating Request | Unable to create the request for the mID credential | Mobile ID reader is not able to create the request, and may abort the transaction |
303 | Transaction Cancelled | The transaction has been cancelled by the user | Unable to scan the QR code |
304 | Connection Failed | Unable to connect the device | BLE connection failure; Mobile ID reader may abort the transaction |
305 | Device Disconnected | Device has disconnected; it might not be in the range of BLE | Mobile ID reader may abort the transaction |
306 | Timed Out; Try again | BLE connection failure; Mobile ID reader may abort the transaction | |
307 | Request Incomplete | Select one or more attributes to be included in the request to the Mobile ID App | None |
308 | Incomplete Request | A 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 |
309 | Request Rejected | Mobile ID back-end indicates that the request is rejected | None |
310 | Mobile ID reader authentication error | Mobile ID back-end indicates there is an error with Mobile ID reader authentication | None |
311 | General Error | Mobile ID back-end returns an error without any given reason | Mobile ID reader may inspect the request, ensure request is complete, and resend it; Mobile ID reader may abort transaction |
400 | Error in response data received | Response data is malformed or nil | |
401 | Parsing Error | Mobile 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 message | Mobile ID reader may inspect the request, ensure request is complete, and resend it; Mobile ID reader may abort the transaction |
402 | Invalid Format | The Mobile ID back-end cannot process the requested data element due to a formatting error | None |
403 | Data Not Found | Requested NameSpace or data element within a NameSpace is not found. | None |
404 | Data Request Denied | Release of requested data element was rejected by Mobile ID credential holder | None |
405 | Data Not Returned | Mobile ID back-end does not provide the requested data element, without any given reason | None |
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.