Skip to content

Android - OCR Module

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

⚠️ Prerequisite: Maven access must be provided before using the OCR Module 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 dependency to the build.gradle.kts file:

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

3. Gradle Sync

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

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


Implementation

1. Permissions

Camera permission is automatically added to the manifest by the SDK and is requested by the SDK at required points. 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 entire screen should be added to the layout of the Activity where the OCR process 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.

Adding to the class:

Text Only
class EnQualifyPlusActivity : AppCompatActivity(), OCRCallbacks

Overriding 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 interrupted.
    }

    override fun initializeCompleted(module: EnModules) {
        Log.i(tag, "${object {}.javaClass.enclosingMethod?.name}")
        when (module) {
            EnModules.OCR -> {
                // OCR operations 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}")
    }
}

Note

The LuminosityFailed error captured via the IDDocFailed() callback is not a critical error. It only indicates that the brightness is not adequate. When this error occurs, the flow should not be interrupted. If desired, a warning related to brightness can be shown.

4. Initializing EnQualifyOCR

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

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
)

Initialization Parameters

Parameter Type Description
context Context The runtime context of the application
sessionModel SessionModel Session information to be used during OCR operations
baseModel BaseModel Model carrying the basic data during the validation 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 initialize() is called, the SDK automatically executes the following steps sequentially:

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

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. The parameter specifies which face should be recognized.
hologramCheckStart() Starts the hologram detection process
iDDocFrontStart(withVisualAnalysis: Boolean = false) Starts scanning the front face of the identity. If set to true, visual element analysis will also take place.
iDDocBackStart(withVisualAnalysis: Boolean = false) Starts scanning the back face of the identity. If set to true, visual element analysis will also take place.
iDDocComplete() Notifies the SDK that all identity reading steps have been completed
addIntegration(integrationModel) Adds integration data
closeSession(isFinished: Boolean) Closes the session
clear() Cleans the SDK
getSessionUId() Returns the UId of the current session.
concealConfigGet() Returns a list of touch test items that can be performed.
frontSignatureConcealCheck() Starts a touch test for the front signature.
frontMliConcealCheck() Starts a touch test for the front MLI.
frontCrescentConcealCheck() Starts a touch test for the front crescent.
backOviConcealCheck() Starts a 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 specifies 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}")
}

ID Back Side 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}")
}

Finishing ID Reading Flow

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

Text Only
enQualifyOCR.iDDocComplete()

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

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

Front Side 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 Side 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 Side 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 Side 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}")
}

Finishing Touch Test

This function is called after the touch test operations have been performed.

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 for through the following callbacks:

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

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

Closing and Clearing Session

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

// Session close 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 SDK (should be called after session is closed)
enQualifyOCR.clear()

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


Obtaining Session Information

Text Only
// Function that returns 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"),   // This is non-fatal — 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 non-fatal. The reading process should not be stopped when this error occurs.


Accessing Result Data

After the OCR reading process is completed, the read data can be accessed via the CustomerIDDoc object:

Text Only
CustomerIDDoc.getInstance()

For the description 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 the 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 close error
integrationAddCompleted() Integration data added successfully
integrationAddFailed(errorMessage: String) Failed 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) ID type successfully detected
hologramCheckVerified() Hologram successfully detected
IDDocFrontCompleted() Front side reading completed
IDDocBackCompleted() Back side reading completed
IDDocSaveStarted() Data transmission to backoffice has started
IDDocCompleted() Data successfully transmitted to 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