OCR
Descripción General
Esta documentación proporciona una guía detallada para desarrolladores sobre cómo integrar e implementar el SDK OCR en sus aplicaciones Android. El SDK permite la captura y procesamiento de datos de documentos de identificación de manera eficiente y segura.
Requisitos Previos
Compatibilidad
| Lenguaje | Versión Android | Versión SDK | Android Studio | Kotlin |
|---|---|---|---|---|
| Kotlin/Java | Android 7+ | 24+ | Jellyfish+ | 2.2.21+ |
Permisos en el Manifest: Asegúrate de agregar los siguientes permisos en tu archivo AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Configuración del Proyecto: Añade las siguientes dependencias en tus archivos:
libs.versions.toml
[versions]
blinkidUxVersion = "8001.0.0"
lottieComposeVersion = "6.7.1"
okhttp3 = "5.4.0"
[libraries]
microblink-blinkid-ux = { group = "com.microblink", name = "blinkid-ux", version.ref = "blinkidUxVersion" }
airbnb-lottie-compose = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "lottieComposeVersion" }
okhttp3 = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp3" }
build.gradle:
dependencies {
implementation(files("libs/sdkocr.aar"))
implementation(libs.airbnb.lottie.compose)
implementation(libs.microblink.blinkid.ux)
}
Uso Básico
El SDK se proporciona como un Composable de Jetpack Compose llamado DicioCamera. Debes invocar este Composable en el punto de tu UI donde deseas mostrar la interfaz de escaneo.
package com.tuapp.yourapp
import ai.dicio.ocrsdk.core.OcrCallback
import ai.dicio.ocrsdk.ui.models.settings.OcrResult
import ai.dicio.ocrsdk.ui.screens.camera.DicioCamera
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import kotlin.time.Duration.Companion.seconds
import android.util.Log
import org.json.JSONException
import org.json.JSONObject
// ... (Tu lógica para obtener el token
// Por ejemplo, usando State para manejar el token
sealed class TokenState {
object Loading : TokenState()
data class Success(val token: String) : TokenState()
data class Error(val message: String) : TokenState()
}
@Composable
fun OcrScreen(tokenState: TokenState, modifier: Modifier = Modifier) {
// ... (Mostrar pantalla de carga, error o el SDK dependiendo del tokenState) ...
when(tokenState) {
TokenState.Loading -> { /* Mostrar indicador de carga */ }
is TokenState.Error -> { /* Mostrar mensaje de error */ }
is TokenState.Success -> {
// Cuando el token está listo, mostrar el DicioCamera
DicioCameraIntegration(token = tokenState.token, modifier = modifier)
}
}
}
@Composable
fun DicioCameraIntegration(token: String, modifier: Modifier = Modifier) {
// Debes proporcionar tu applicationId y la URL base de tu API
val myApplicationId = "tu.application.id" // Reemplaza con tu Application ID real
val myUrlBase = "https://tu_url" // Reemplaza con tu URL base real
val ocrCallback = remember {
object : OcrCallback {
override fun onSuccess(result: OcrResult) {
// Escaneo exitoso. Procesa los datos recibidos.
Log.d("OCR_SDK", "Escaneo exitoso!")
Log.d("OCR_SDK", "Result Data: ${result.resultData}") // Datos extraídos en formato JSON
Log.d("OCR_SDK", "Face Image B64 (primeros 50 chars): ${result.faceImageBase64.take(50)}...")
Log.d("OCR_SDK", "Front Image B64 (primeros 50 chars): ${result.frontImageBase64.take(50)}...")
Log.d("OCR_SDK", "Back Image B64 (primeros 50 chars): ${result.backImageBase64.take(50)}...")
// Aquí puedes navegar y cerrar la pantalla del SDK y procesarías los datos
}
override fun onGuidanceMessage(message: String) {
// Mensajes de guía durante el escaneo
Log.d("OCR_SDK", "Mensaje de guía: $message")
// Puedes parsear el 'message' para obtener el código
val code = getCodeFromJsonString(message)
when (code) {
"UX_REQUEST_SIDE_BACK" -> Log.d("OCR_SDK", " -> Se solicita escanear el lado trasero.")
"UX_REQUEST_SIDE_FRONT" -> Log.d("OCR_SDK", " -> Se solicita escanear el lado delantero.")
// Manejar otros códigos si es necesario
}
}
override fun onFailure(error: String) {
// Ocurrió un error que impidió completar el escaneo
Log.e("OCR_SDK", "Error en el escaneo: $error")
// cerrar o navegar pantalla del SDK y notificarías al usuario
}
override fun onCancel(message: String) {
// El escaneo fue cancelado (por el usuario o por tiempo de espera)
Log.w("OCR_SDK", "Escaneo cancelado: $message")
// cerrar o navegar pantalla del SDK y notificarías al usuario
}
}
}
// Invocar el Composable DicioCamera
DicioCamera(
callback = ocrCallback,
applicationID = myApplicationId,
token = token, // El token obtenido previamente
urlBase = myUrlBase, // Tu URL base de API
seconds = 60, // Tiempo máximo para el escaneo
)
}
// Función auxiliar para extraer el código del mensaje JSON
fun getCodeFromJsonString(jsonString: String): String? {
return try {
val jsonObject = JSONObject(jsonString)
if (jsonObject.has("Code")) {
jsonObject.getString("Code")
} else {
null
}
} catch (e: JSONException) {
e.printStackTrace()
null
}
}
Parámetros de DicioCamera
| Parámetro | Tipo | Descripción | Obligatorio | Valor por defecto |
|---|---|---|---|---|
callback | OcrCallback | Implementación de la interfaz OcrCallback para recibir los resultados, mensajes de guía, errores y cancelaciones del SDK. | Sí | Ninguno |
applicationID | String | El ID de tu aplicación. Utilizado internamente por el SDK para la gestión de licencias. | Sí | Ninguno |
token | String | Token de autenticación. Utilizado por el SDK para validar la sesión y obtener la licencia desde tu API. Debe ser un token válido. | Sí | Ninguno |
urlBase | String | La URL base de tu API donde el SDK puede validar el token y obtener la configuración de la licencia. | Sí | Ninguno |
seconds | Int | Duración máxima permitida para el proceso de escaneo. Si se excede, el SDK se cancelará automáticamente con el código TIMEOUT_CANCEL. | No | 50 |
styledScreen | OcrStyled | Objeto que permite personalizar la apariencia de la interfaz del SDK (colores, textos, logo). | No | OcrStyled() |
Manejo de Resultados y Eventos
Debe implementar la interfaz OcrCallback para recibir las respuestas y eventos del SDK.
data class OcrResult(
val resultData: String,
val faceImageBase64: String,
val frontImageBase64: String,
val backImageBase64: String
)
interface OcrCallback {
// Se llama cuando el escaneo se completa con éxito y se extraen los datos
fun onSuccess(result: OcrResult)
// Se llama para proporcionar mensajes de guía al usuario durante el escaneo
fun onGuidanceMessage(message: String) // Mensaje JSON con un código y descripción
// Se llama cuando ocurre un error que impide completar el escaneo
fun onFailure(error: String) // Mensaje descriptivo del error
// Se llama cuando el proceso de escaneo es cancelado
fun onCancel(message: String) // Mensaje descriptivo de la cancelación (ej. usuario, timeout)
}
Métodos a implementar
Métodos:
onSuccess:
- Descripción: Se invoca cuando la verificación de ocr es exitosa.
- Parámetros:
result: ObjetoOcrResultque contiene elresultData(JSON) y las imágenes extraídas (faceImageBase64,frontImageBase64,backImageBase64).
onGuidanceMessage:
- Descripción: Se invoca durante el proceso de escaneo.
- Parámetros:
message: eventos ux.
- Tabla de codigos:
Código Descripción UX_REQUEST_SIDE_FRONTSe solicita al usuario escanear el lado delantero del documento. UX_REQUEST_SIDE_BACKSe solicita al usuario escanear el lado trasero del documento. DOCUMENT_NOT_FOUNDEl documento no fue detectado en el encuadre de la cámara. UX_DOCUMENT_NOT_FULLY_VISIBLEEl documento no está completamente visible en el encuadre. UX_DOCUMENT_LOCATEDEl documento ha sido detectado y ubicado correctamente en el encuadre. UX_DOCUMENT_TOO_FAREl documento está demasiado lejos de la cámara. UX_DOCUMENT_TOO_CLOSEEl documento está demasiado cerca de la cámara. UX_TOO_CLOSE_TO_EDGEEl documento está demasiado cerca del borde del encuadre de la cámara. UX_DOCUMENT_TOO_TILTEDEl documento está demasiado inclinado. UX_BLUR_DETECTEDSe ha detectado desenfoque. La imagen no está nítida. UX_GLARE_DETECTEDSe ha detectado brillo o reflejo en el documento. Evitar la luz directa. UX_WRONG_SIDESe está intentando escanear el lado incorrecto del documento. UX_SCANNING_DONEEl proceso de escaneo UX (captura visual) ha finalizado. UX_UNKNOWN_EVENTSe recibió un evento de interfaz de usuario desconocido.
onFailure:
- Descripción: Se invoca cuando hay un error durante el proceso.
- Parámetro:
error: Mensaje descriptivo del error en formato JSON.
- Tabla de codigos:
Código Descripción DOCUMEN_NOT_VALIDEl documento escaneado no es válido. ERROR_PERMISSIONPermiso de cámara denegado. ERROR_SDKError interno del SDK o licencia no valida. UNRECOVERABLE_ERROROcurrió un error crítico no recuperable. TOKEN_EMPTYEl token está vacío o falta. NO_INTERNETNo hay conexión a internet. LICENCE_OR_TOKEN_ERRORLicencia o token inválido. TOKEN_NOT_VALIDToken no válido. onCancel:
- Descripción: Se invoca cuando el usuario cancela la verificación.
- Parámetro:
message: Mensaje explicando por qué se canceló el proceso.
- Tabla de codigos:
Código de cancelación Descripción TIMEOUT_CANCELLa sesión fue cancelada por exceder el tiempo límite permitido (1 minuto). USER_CANCELEl usuario canceló el proceso.
Personalización de la Interfaz (Opcional)
Si deseas personalizar la apariencia de la pantalla de escaneo (textos, colores, logo), puedes hacerlo proporcionando un objeto OcrStyled al parámetro styledScreen.
El objeto OcrStyled es una data class con los siguientes campos:
val styledSdk = OcrStyled(
modalTitle = R.string.ocr_modal_title_instructions,
modalContent = R.string.ocr_modal_subtitle_instructions,
timeoutModalTitle = R.string.ocr_modal_timeout_title_instructions,
timeoutModalContent = R.string.ocr_modal_timeout_subtitle_instructions,
logo = R.drawable.logo,
titleColor = Color.Black,
contentColor = Color.Gray,
iconColor = Color.White,
scannerColor = Color.White,
timeoutModalButtonText = R.string.button_cancel,
backgroundColor = Color.White
)
Ejemplo de cómo consumirlo:
DicioCamera(
callback = sdkCallback,
applicationID = viewModel.aplicationId,
token = token,
urlBase = viewModel.urlBase,
seconds = viewModel.timeOut,
styledScreen = styledSdk
)