Skip to content

Android - OCR Module

The OCR module reads data from identity cards or passports using images taken from the rear camera. It performs visual object analysis, hologram detection, front/back face reading, and MRZ area reading operations.

⚠️ Prerequisite: Before using the OCR Module, Maven access must be provided and the Core Module must be added to the project.


Adding to the Project

1. Add to the libs.versions.toml file:

Text Only
[versions]
...
enqualify-plus = "x.x.x.x"

[libraries]
...
enqualify-plus-ocr = {
    group = "com.enqualify.plus",
    name = "ocr",
    version.ref = "enqualify-plus"
}

2. Add the dependency to the build.gradle.kts file:

Text Only
implementation(libs.enqualify.plus.ocr)

3. Gradle Sync

Synchronize the Gradle files by clicking on the "Sync Now" option.

ℹ️ The version number must be the same across all modules.


Implementation

1. Permissions

Camera permission is automatically added to the manifest by the SDK and requested at necessary points by the SDK. The following line is for informational purposes only:

Text Only
<uses-permission android:name="android.permission.CAMERA" />

The OCR module will not work if camera permission is not granted.

2. Activity Layout — FrameLayout

A FrameLayout that covers the full screen must be added to the layout of the Activity where the OCR operation will take place. The SDK manages camera screens and page transitions through this component:

Text Only
<FrameLayout
    android:id="@+id/fragmentContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3. Adding the OCRCallbacks Interface

The OCRCallbacks interface contains the necessary callback methods to manage OCR operations and must work with an Activity.

Add to the class:

Text Only
class EnQualifyPlusActivity : AppCompatActivity(), OCRCallbacks

Override the callbacks:

Text Only
class EnQualifyPlusActivity : AppCompatActivity(), OCRCallbacks {

    override fun IDDocTypeCheckVerified(isFront: Boolean) {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun IDDocFrontCompleted() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun hologramCheckVerified() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun IDDocBackCompleted() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun IDDocSaveStarted() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun IDDocCompleted() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun IDDocFailed(ocrFailureCode: OCRFailureCode, additionalMessage: String?) {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
        // LuminosityFailed is not a critical error; reading should not be stopped.
    }

    override fun initializeCompleted(module: EnModules) {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
        when (module) {
            EnModules.OCR -> {
                // OCR processes can be initiated
            }
        }
    }

    override fun initializeFailed(failureCode: FailureCode, additionalMessage: String) {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun FrontCrescentConcealChecked() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun FrontMliConcealChecked() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun FrontSignatureConcealChecked() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun BackOviConcealChecked() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }

    override fun IDDocConcealCompleted() {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
    }
}

The LuminosityFailed error will be captured through the IDDocFailed() callback and is not a critical error. It simply indicates that the brightness is not suitable. When this error occurs, the flow should not be interrupted. If desired, a related warning about brightness can be displayed.

4. Initializing EnQualifyOCR

Before starting OCR operations, EnQualifyOCR.initialize() must be called. If another operation is attempted without initialization, the SDK will not work.

Text Only
val sessionModel = SessionModel(
    callType = "NewCustomer",
    reference = UUID.randomUUID().toString()
)

val baseModel = BaseModel(
    baseURL = "https://deveqmapi.enqura.com",
    signallingCertificateList = listOf("enqura"),
    mapiCertificateList = listOf("enqura"),
    mobileUser = "mobile",
    countryCode = "TUR",
    locale = "TR",
    useEmbeddedLocalSound = false
)

EnQualifyOCR.initialize(
    context = this,
    fragmentManager = supportFragmentManager,
    containerID = R.id.fragmentContainer,
    sessionModel = sessionModel,
    baseModel = baseModel
)

Initialize Parameters

Parameter Type Description
context Context The runtime context of the application
sessionModel SessionModel Session information to be used during the OCR process
baseModel BaseModel Model carrying basic data during the verification process
fragmentManager FragmentManager Manages the OCR fragments
containerID Int The ID of the container where the OCR fragment will be added

Automatic Flow After Initialization

After the initialize() is called, the SDK automatically executes the following steps in order:

  1. Token Creation If the token creation fails, tokenCreateFailed is triggered:
Text Only
override fun tokenCreateFailed(errorMessage: String) {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name} $errorMessage")
}
  1. Session Start If the session start fails, sessionAddFailed is triggered:
Text Only
override fun sessionAddFailed(errorMessage: String) {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}
  1. Getting Settings If the settings cannot be retrieved, settingsGetFailed is triggered:
Text Only
override fun settingsGetFailed(errorMessage: String) {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}
  1. Completion Once all steps are successfully completed, initializeCompleted is triggered, and OCR operations can be initiated.

OCR Operations

Functions

Function Description
addFragment(fragment) Adds a new fragment on top of the current fragment
replaceFragment(fragment) Replaces the current fragment with a new one
iDDocTypeCheckStart(isFront: Boolean = true) Starts the identity type recognition process. Indicates which face needs to be recognized with the parameter it receives.
hologramCheckStart() Starts the hologram detection process
iDDocFrontStart(withVisualAnalysis: Boolean = false) Starts scanning the front face of the identity. If the parameter is set to true, visual elements will also be analyzed.
iDDocBackStart(withVisualAnalysis: Boolean = false) Starts scanning the back face of the identity. If the parameter is set to true, visual elements will also be analyzed.
iDDocComplete() Notifies the SDK that all identity reading steps are completed
addIntegration(integrationModel) Adds integration data
closeSession(isFinished: Boolean) Closes the session
clear() Clears the SDK
getSessionUId() Returns the UId of the current session.
concealConfigGet() Returns the touch test elements that can be performed in list form.
frontSignatureConcealCheck() Starts the touch test for the front signature.
frontMliConcealCheck() Starts the touch test for the front MLI.
frontCrescentConcealCheck() Starts the touch test for the front crescent.
backOviConcealCheck() Starts the touch test for the back face OVI.
idDocConcealComplete() Ends the touch test.

Identity Type Recognition

Text Only
enQualifyOCR.iDDocTypeCheckStart(isFront = true)

When the process is completed, IDDocTypeCheckVerified is triggered. The isFront parameter indicates which face of the identity will be identified.

Text Only
override fun IDDocTypeCheckVerified(isFront: Boolean) {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Identity Front Face Scanning

Text Only
enQualifyOCR.iDDocFrontStart(withVisualAnalysis = true)

When the process is completed, IDDocFrontCompleted is triggered:

Text Only
override fun IDDocFrontCompleted() {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Hologram Detection

Text Only
enQualifyOCR.hologramCheckStart()

When the process is completed, hologramCheckVerified is triggered:

Text Only
override fun hologramCheckVerified() {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Identity Back Face Scanning

Text Only
enQualifyOCR.iDDocBackStart(withVisualAnalysis = true)

When the process is completed, IDDocBackCompleted is triggered:

Text Only
override fun IDDocBackCompleted() {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Ending the Identity Reading Flow

When all steps are completed, iDDocComplete() is called. This function stops the camera analysis, ends the processing, and starts sending the read data to the backoffice:

Text Only
enQualifyOCR.iDDocComplete()

When the data is successfully sent to the backoffice, IDDocCompleted is triggered:

Text Only
override fun IDDocCompleted() {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Front Crescent Touch Test

This step can only be performed after the OCR process is completed.

Text Only
enQualifyOCR.frontCrescentConcealCheck()

When the touch test is successful, FrontCrescentConcealChecked is triggered:

Text Only
override fun FrontCrescentConcealChecked {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Front Signature Touch Test

This step can only be performed after the OCR process is completed.

Text Only
enQualifyOCR.frontSignatureConcealCheck()

When the touch test is successful, FrontSignatureConcealChecked is triggered:

Text Only
override fun FrontSignatureConcealChecked {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Front MLI (Ghost Image) Touch Test

This step can only be performed after the OCR process is completed.

Text Only
enQualifyOCR.frontMliConcealCheck()

When the touch test is successful, FrontMliConcealChecked is triggered:

Text Only
override fun FrontMliConcealChecked {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Back OVI Touch Test

This step can only be performed after the OCR process is completed.

Text Only
enQualifyOCR.backOviConcealCheck()

When the touch test is successful, BackOviConcealChecked is triggered:

Text Only
override fun BackOviConcealChecked {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Ending the Touch Test

After the touch test operations are performed, this function is called.

Text Only
enQualifyOCR.idDocConcealComplete()

When the process is completed, idDocConcealCompleted is triggered:

Text Only
override fun idDocConcealCompleted {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

Adding Integration Data

Text Only
val integrationModel = IntegrationModel(
    idRegistration = IDRegistration(),
    addressRegistration = AddressRegistration(),
    data = ""
)
enQualifyOCR.addIntegration(integrationModel)

Results are listened to through the following callbacks:

Text Only
override fun integrationAddCompleted() {
    Log.i(TAG, "integrationAddCompleted")
}

override fun integrationAddFailed(errorMessage: String) {
    Log.i(TAG, "integrationAddFailed: $errorMessage")
}

Closing Session and Clearing

Text Only
// Close the session
enQualifyOCR.closeSession(isFinished = true)

// Session closure callbacks
override fun sessionCloseCompleted() {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

override fun sessionCloseFailed(errorMessage: String) {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name} $errorMessage")
}

// Clear the SDK (should be called after the session is closed)
enQualifyOCR.clear()

ℹ️ After closing the session, initialize() must be called again to reuse the SDK.


Getting Session Information

Text Only
// Function that returns the SessionUId
enQualifyOCR.getSessionUId()

Error Management

FailureCode (Core / Initialize Errors)

Text Only
enum class FailureCode(val errorMessage: String) {
    CameraError("Unable to access the camera. Please check device settings and retry."),
    CameraStartError(""),
    CameraNotSupported("Failed to initialize the camera. Device may not support required resolution or FPS."),
    SdkInitializationError("Required sdk initialization did not completed."),
    CameraPermissionDenied("Camera permission denied"),
    CertificateFailed("Certificate failed"),
    AIModelNotFound("AI model not found"),
    NfcCertificateNotFound("Nfc Certificate not found")
}

It is communicated through the initializeFailed callback:

Text Only
override fun initializeFailed(failureCode: FailureCode, additionalMessage: String) {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

OCRFailureCode (OCR Process Errors)

Text Only
enum class OCRFailureCode(errorMessage: String) {
    IDDocSaveFailed("save failed"),
    LuminosityFailed("Luminosity failed"),   // Is not critical — reading should not be stopped
    TypeCheckFailed(""),
    HologramCheckError(""),
    VisualAnalysingFrontError(""),
    VisualAnalysingBackError(""),
    ReadIdDocFrontError(""),
    ReadIdDocBackError(""),
    ReadPassportError(""),
    IDDocError(""),
    CameraError("Unable to access the camera. Please check device settings and retry."),
    CameraStartError(""),
    CameraNotSupported("Failed to initialize the camera. Device may not support required resolution or FPS."),
    SdkInitializationError("Required sdk initialization did not completed."),
    CameraPermissionDenied("Camera permission denied"),
    Failed(""),
    IDDocTimeout("Timeout")
}

It is communicated through the IDDocFailed callback:

Text Only
override fun IDDocFailed(ocrFailureCode: OCRFailureCode, additionalMessage: String?) {
    Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
}

⚠️ Important: LuminosityFailed is a warning and is not critical. When this error occurs, the reading process should not be interrupted.


Accessing Result Data

Once the OCR reading process is completed, the read data can be accessed through the CustomerIDDoc object:

Text Only
CustomerIDDoc.getInstance()

For the explanation of the CustomerIDDoc model and all its fields, refer to the Core Module — CustomerIDDoc page.


Callback Reference

Token / Session / Settings

Callback Description
tokenCreateCompleted(isNewCreatedToken: Boolean) Triggered when a token is created
tokenCreateFailed(errorMessage: String) Token creation error
sessionAddFailed(errorMessage: String) Session creation error
settingsGetFailed(errorMessage: String) Triggered when settings cannot be retrieved
sessionCloseCompleted(status: CallSessionTypeStatus) Triggered when the session is closed
sessionCloseFailed(errorMessage: String) Session closing error
integrationAddCompleted() Integration data has been successfully added
integrationAddFailed(errorMessage: String) Unable to add integration data
initializeFailed(failureCode: FailureCode, additionalMessage: String) Core initialize error

OCR

Callback Description
initializeCompleted(module: EnModules) Initialization completed, OCR ready
IDDocTypeCheckVerified(isFront: Boolean) Identity type successfully identified
hologramCheckVerified() Hologram successfully detected
IDDocFrontCompleted() Front face reading completed
IDDocBackCompleted() Back face reading completed
IDDocSaveStarted() Data started to be sent to the backoffice
IDDocCompleted() Data successfully sent to the backoffice
IDDocFailed(ocrFailureCode, additionalMessage) OCR process error
FrontCrescentConcealChecked() Front crescent touch detected
FrontMliConcealChecked() Front MLI touch detected
FrontSignatureConcealChecked() Front signature touch detected
BackOviConcealChecked() Back OVI touch detected
IDDocConcealCompleted() Touch test completed