DDLens Docs
Native Android SDK

Build identity scanning into Android.

Integrate AAMVA PDF417 and ICAO MRZ scanning with Kotlin, CameraX, ML Kit, and a still-image ZXing fallback.

v1.9.0 · StableAndroid 8.0+API 26+Java 17

Overview

DLens processes camera frames and document payloads on device. Driver licences use PDF417; passports, national IDs, and residence documents use ICAO TD1, TD2, or TD3 machine-readable zones. MRZ results must pass check-digit validation.

Requirements

  • Android API 26+ and compile SDK 35+
  • Java 17 and AndroidX
  • A physical camera device for live scanning
  • Credentials issued for the exact Android applicationId

Installation

Unpack the distribution beside your app and include the library module.

settings.gradle.kts
include(":dlens-sdk")
project(":dlens-sdk").projectDir =
    file("../DLensAndroid/dlens-sdk")
app/build.gradle.kts
dependencies {
    implementation(project(":dlens-sdk"))
}

The library manifest contributes camera permission and the private scanner activity.

Initialise

Application.kt
DLens.initialize(
    context = applicationContext,
    apiKey = BuildConfig.DLENS_API_KEY,
    secret = BuildConfig.DLENS_SECRET,
    configuration = DLensConfiguration(
        scanMode = ScanMode.ALL,
        timeoutSeconds = 60,
    ),
)

Present the supplied scanner

DLensScannerActivity requests permission, manages the camera, and returns result JSON.

ScanActivity.kt
private val scan = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { response ->
    when (response.resultCode) {
        Activity.RESULT_OK -> {
            val json = response.data?.getStringExtra(
                DLensScannerActivity.EXTRA_RESULT
            )
        }
        Activity.RESULT_CANCELED -> Unit
        else -> {
            val code = response.data?.getStringExtra(
                DLensScannerActivity.EXTRA_ERROR_CODE
            )
        }
    }
}

scan.launch(
    Intent(this, DLensScannerActivity::class.java)
        .putExtra(DLensScannerActivity.EXTRA_MODE, ScanMode.ALL.name)
)

Result dates are ISO yyyy-MM-dd strings.

Embed a custom preview

Request camera permission, then attach DLensScanner to a CameraX PreviewView.

Kotlin
val scanner = DLensScanner(
    context = this,
    lifecycleOwner = this,
    previewView = binding.preview,
    mode = ScanMode.ALL,
)
scanner.start(
    onResult = ::showResult,
    onError = { showError(it.message.orEmpty()) },
)
scanner.setTorch(true)
scanner.setZoom(1.5f)

// Release in onDestroy:
scanner.stop()

Create a new scanner for each session. stop() releases its analysis executor.

Scan an existing image

Kotlin
DLens.scan(bitmap, mode = ScanMode.ALL) { outcome ->
    outcome.onSuccess(::showResult)
    outcome.onFailure { showError(it.message.orEmpty()) }
}

Parse a payload

Kotlin
val result = DLens.parse(rawAamvaOrMrzText)

Configuration

PropertyDefaultPurpose
scanModeBARCODE_ONLYBarcode, MRZ, or both
timeoutSeconds60Zero disables timeout
autoZoomtrueAutomatic zoom policy
minZoom / maxZoom1.0 / 2.5Allowed zoom range
rescanZoomOffset0.5Adjustment for another pass
dismissBehaviorAUTOMATICAutomatic or manual dismissal

Visibility preferences are also available for cancel, torch, zoom, tips, instructions, and the mode badge. Use DLens.configure(...) after initialization.

Result model

Required: first name, last name, licence/document number, and raw payload. Optional fields cover other names, dates, licence details, address, country, gender, eye colour, and height. fullName joins present name components.

Errors

Catch DLensException: NotInitialized, InvalidApiKey, InvalidSecret, LicenseExpired, LicenseKeyMismatch, CameraPermissionDenied, Timeout, and ScanningFailed.

Credentials and validation

Keep production credentials out of source control and inject them through protected build configuration.

Camera-level accuracy must be benchmarked on representative physical devices against the same document corpus used for the iOS release.