# Android

**BCC Face** es una biblioteca de Android destinada a integrarse en una aplicación Android.

Utiliza la cámara del dispositivo para tomar una foto de un rostro con fines biométricos. Proporciona una sencilla prueba activa de detección de vida, que requiere que la persona sonría durante aproximadamente un segundo y/o mire hacia la derecha o hacia la izquierda. La prueba de detección de vida incluye una opción para leer las instrucciones en voz alta, facilitando el flujo de trabajo para los usuarios. Además, proporciona una prueba pasiva de detección de vida que puede usarse para verificar si la foto fue tomada de una persona real sin requerir interacción del usuario.

Este manual está actualizado para la versión de BCC Face Mobile Android `4.11.3`.

{% hint style="warning" %}
La **prueba pasiva de detección de vida** está disponible solo a partir de la versión `4.4.0` en adelante.
{% endhint %}

## Requisitos

BCC Face es una biblioteca de Android y debe importarse en el proyecto de destino.

* Versión mínima de Android: Android 6.0 (SDK 23), "Marshmallow".
* El dispositivo móvil debe tener cámara.
* La aplicación nativa debe estar desarrollada usando tecnología Android.
* Entorno de desarrollo: se requiere un IDE de Android, como Android Studio (recomendado).
* Dependencias externas adicionales:
  * Google ML Kit, detección de rostros versión 16.1.7;
  * Lottie, versión 3.0.0;
  * RootBeer, versión 0.1.1;
  * Gson, versión 2.8.5;
  * Google Tink, versión 1.11.0;
  * Material Components, versión 1.6.1.
* Servicios externos:
  * Firebase, de Google. Se requiere una cuenta, pero no se aplicarán cargos, ya que la biblioteca solo usa API en el dispositivo.

## Instalación

### Agregar la biblioteca en el proyecto de la app

BCC Face es proporcionado por Griaule como un `.aar` archivo.

Para agregar las bibliotecas, vaya al directorio de su proyecto, abra la carpeta **app** y cree los directorios: `libs/bccface`. Luego, agregue la dependencia `bccfacelib-release.aar` . La estructura de carpetas debe ser similar a esta:

![](/files/f995f1d01ea4f65708c79868efd78234338d83d0)

El siguiente paso es hacer que estos archivos sean visibles para las dependencias de gradle. Para ello, agregue la siguiente línea en el archivo `build.gradle (:app)`, en el objeto dependencies:

```groovy
dependencies {
	[...]
	implementation fileTree(dir: 'libs/bccface', include: ['*.aar'])
}
```

Dentro del `build.gradle (:app)` archivo, agregue también las opciones de compilación y establezca Source Compatibility y Target Compatibility para usar Java 17:

```groovy
compileOptions {
	sourceCompatibility JavaVersion.VERSION_17
	targetCompatibility JavaVersion.VERSION_17
}
```

### Configuración de Google ML Kit

Se recomienda seguir las instrucciones proporcionadas en "[Opción 1: Use el flujo de trabajo de configuración de la consola de Firebase](https://firebase.google.com/docs/android/setup#console)" de la documentación de Firebase para Android: [Agregar Firebase a su proyecto Android](https://firebase.google.com/docs/android/setup).

Se requiere una cuenta, pero no se aplicarán cargos, ya que la biblioteca usa solo API en el dispositivo: [Ver detalles de precios de Firebase](https://firebase.google.com/pricing/).

Si [Opción 1](https://firebase.google.com/docs/android/setup#console) fue elegida, asegúrese de generar el archivo `google-services.json` y de colocarlo en el directorio `android/app/` .

Realice cambios en los siguientes archivos:

* `android/build.gradle`

  ```groovy
  buildscript {
  	// ...
  	dependencies {
  		// ...
  		classpath 'com.google.gms:google-services:4.4.2'
  	}
  }
  ```
* `android/app/build.gradle`, agregue al final del archivo:

  ```groovy
  // ...

  apply plugin: 'com.android.application'
  apply plugin: 'kotlin-android'
  apply plugin: 'kotlin-kapt'
  apply plugin: 'com.google.gms.google-services'

  // ...

  android {
  	// ...
  	buildFeatures {
  		viewBinding = true
  		dataBinding = true
  	}
  }

  // ...

  dependencies {
  	// ...
  	implementation 'com.google.firebase:firebase-analytics:17.2.2'
  	// Añada la línea anterior usando analytics
  }
  ```

### Configurando todas las dependencias

Realice cambios en los siguientes archivos:

* `android/build.gradle`

  ```groovy
  allprojects {
  	repositories {
  		// ...
  		google()
  		mavenCentral()
  		maven { url 'https://jitpack.io' }
  	}
  }
  ```
* `android/app/build.gradle`

  ```groovy
  // ...
  dependencies {
  	// ...
  	implementation project(path: ':bccfacelib')

  	// ANDROIDX //
  	implementation 'androidx.appcompat:appcompat:1.7.0'
  	implementation 'androidx.core:core-ktx:1.13.1'
  	implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

  	// Google MLKIT //
  	implementation 'com.google.mlkit:face-detection:16.1.7'

  	// LOTTIE //
  	implementation 'com.airbnb.android:lottie:3.0.0'

  	// CAMERA X //
  	def camerax_version = "1.5.1"
  	implementation "androidx.camera:camera-camera2:$camerax_version"
  	implementation "androidx.camera:camera-lifecycle:$camerax_version"
  	implementation "androidx.camera:camera-view:$camerax_version"

  	// MATERIAL //
  	implementation 'com.google.android.material:material:1.6.1'
  }
  ```

## Uso

### Parámetros y constructor

Para usar correctamente la biblioteca BCC Face, hay algunos parámetros requeridos.

A continuación se muestra un ejemplo sencillo de uso de la biblioteca:

```kotlin
BCCFaceBuilder(this, this).initializeCapture()
```

***

La `BCCFaceBuilder` el constructor de la clase recibe los siguientes parámetros:

* `context: Context` - El contexto de la aplicación.
* `delegate: BCCFaceDelegate` - Interfaz responsable de notificar eventos de captura (por ejemplo, fallo o éxito).

***

La `BCCFaceBuilder` la clase es responsable de gestionar la configuración de uso para `BCC Face`. Se aceptan los siguientes parámetros para configurar la captura biométrica y el comportamiento del software:

* `buildSmileCheck(smileProbability: Float = 0.8f)` - Agrega la sonrisa para la prueba de detección de vida y define el umbral de aceptación. Esta función está habilitada de forma predeterminada.
* `removeSmileCheck()` - Elimina la sonrisa de la verificación de detección de vida.
* `buildRotationCheck(livenessConfigList: List<HeadRotationCheck>, headRotationAngle: Float = 20f)` - Define una lista de pruebas de detección de vida para la rotación de la cabeza y el ángulo máximo de rotación. Esta función está habilitada de forma predeterminada. Las opciones de rotación de la cabeza son:

  ```kotlin
  enum class HeadRotationCheck {
  	randomRotation,
  	leftRotation,
  	rightRotation;
  }
  ```
* `removeHeadRotation()` - Elimina la rotación de cabeza de la verificación de detección de vida.
* `addPassiveLiveness()` - Agrega la prueba pasiva de detección de vida. Esta función se usa para verificar si la foto capturada proviene de una persona real sin requerir ninguna interacción del usuario. Para usar esta función, DEBE deshabilitar las verificaciones activas de detección de vida (`removeSmileCheck()` y `removeHeadRotation()`) que se agregan de forma predeterminada.
* `buildSpeechSettings(speechSettings: SpeechSettings?)` - Define los criterios para el habla de accesibilidad, usando los siguientes parámetros:

  ```kotlin
  class SpeechSettings(
  	val volume: Float = 1.0f,
  	val startsMuted: Boolean = true,
  	val pitch: Float = 1.0f,
  	val speed: Float = 1.0f
  )
  ```

  * `volume` - El volumen de audio entre `0.0` y `1.0`.
  * `startsMuted` - Define si las instrucciones comienzan silenciadas o no (`true` para silenciado).
  * `pitch` - Define el tono de voz de las instrucciones entre `0.5` (bajo) y `2.0` (alto).
  * `speed` - Define la velocidad de voz de las instrucciones. Este valor debe ser positivo.

  Los valores predefinidos pueden accederse a través de la variable estática:

  ```groovy
  class SpeechSettings {
  	companion object {
  		val defaultSpeechSettings = SpeechSettings()
  	}
  }
  ```
* `removeSpeech()` - Elimina el habla de accesibilidad.
* `setInstructionEnable(enable: Boolean)` – Define si la pantalla de instrucciones está habilitada o deshabilitada.
* `forceLanguage(language: BCCFaceAPI.BCCLanguages?)` - Fuerza a que las instrucciones se muestren en un solo idioma. Si el idioma del dispositivo no es compatible, se usará inglés. Los idiomas compatibles son:

  ```kotlin
  enum class BCCLanguages(val locale: Locale) {
  	ptBR(Locale("pt", "br")),
  	enUS(Locale.US),
  	esMX(Locale("es", "mx")),
  	deviceLanguage(Locale.getDefault());
  }
  ```
* `removeLanguage()` - Elimina el idioma forzado.
* `enableFlipCameraButton(enable: Boolean)` - Activa (`true`) o desactiva (`false`) el botón para cambiar de cámara (cámara frontal o trasera). Predeterminado: habilitado (`true`).
* `enableFlashButton(enable: Boolean)` – Habilita (`true`) o deshabilita (`false`) el botón de flash en la cámara trasera. Predeterminado: deshabilitado (`false`).
* `enableManualCapture(enable: Boolean)` – Habilita (`true`) o deshabilita (`false`) el botón de captura manual, permitiendo al usuario omitir las comprobaciones de captura automática. Al realizar una captura manual, el usuario podrá revisar la foto capturada antes de completar el proceso.
* `enableIntegrityValidation(clientSecret: ByteArray, nonce: ByteArray)` – Habilita la validación de integridad para la detección pasiva de vida, añadiendo una capa extra de seguridad para garantizar la integridad del payload.
* `setImageCompressionFormat(format: ImageCompressionFormat)` – Define el formato de compresión para una captura de detección pasiva de vida. Las opciones disponibles son `ImageCompressionFormat.JPEG` (predeterminado) o `ImageCompressionFormat.JPEG200`.
* `setCameraInitialDirection(CameraFacingDirection.<FRONT or BACK>)` – Define la dirección inicial de la cámara. Elija entre:
  * `CameraFacingDirection.FRONT` – Cámara frontal (configuración predeterminada).
  * `CameraFacingDirection.BACK` – Cámara trasera.

***

Todas las configuraciones de dirección de la cámara se obtienen mediante la combinación de los métodos `enableFlipCameraButton` y `setCameraInitialDirection` . Por ejemplo:

* Comenzar con la cámara frontal y habilitar el botón para cambiar de cámara:

  ```kotlin
  BCCFaceBuilder(this, this)
  	.enableFlipCameraButton(true)
  	.setCameraInitialDirection(CameraFacingDirection.FRONT)
  ```
* Comenzar con la cámara trasera y deshabilitar el botón para cambiar de cámara:

  ```kotlin
  BCCFaceBuilder(this, this)
  	.enableFlipCameraButton(false)
  	.setCameraInitialDirection(CameraFacingDirection.BACK)
  ```

***

Como referencia, aquí hay una lista completa de parámetros y valores predeterminados:

```kotlin
var showInstructionScreen: Boolean = false,
var stopVerifyEyesOpenTimeout: Long = 20,
var useICAO: Boolean = false,
var smilingProbabilityThreshold: Float = 0.8f,
var rotateAngle: Float = 20f,
var livenessList: MutableList<LivenessTypes> = mutableListOf(LivenessTypes.SMILE),
var rotationChecks: MutableList<HeadRotationCheck> = mutableListOf(HeadRotationCheck.randomRotation),
var language: BCCFaceAPI.BCCLanguages? = null,
var speechSettings: SpeechSettings? = SpeechSettings(),
var activityResults: FaceCaptureActivityResults? = null,
var enableFlipCameraButton: Boolean = false,
var enableManualCapture: Boolean = false,
var initCameraFaceDirection: Int = CameraSelector.LENS_FACING_FRONT,
var imageCompressionFormat: ImageCompressionFormat = ImageCompressionFormat.JPEG,
var integrityValidationData: IntegrityValidationData? = null
```

{% hint style="warning" %}
La prueba activa de detección de vida (usando sonrisa y rotación aleatoria de la cabeza) está habilitada de forma predeterminada. Para usar solo la verificación pasiva de detección de vida, antes de agregarla, es necesario eliminar los métodos de detección de vida activa del constructor:

```kotlin
BCCFaceBuilder(this, this)
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness()
```

{% endhint %}

Aquí hay un fragmento de código para inicializar una captura usando solo la prueba pasiva de detección de vida:

```kotlin
// Desde la Activity deseada...

// Crear el builder
BCCFaceBuilder faceBuilder = new BCCFaceBuilder(this, this);

// Configurar el builder
faceBuilder
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness();

// Inicializar la captura desde el builder
faceBuilder.initializeCapture();
```

### Valores de retorno

Los resultados de la última captura facial pueden recuperarse usando el método `faceCaptureDidFinish` de la interfaz `BCCFaceDelegate` :

```kotlin
fun faceCaptureDidFinish(
	data: BCCFaceReturnData,
	analytics: BCCFaceReturnAnalytics
)
```

La `data` el objeto contiene ambas imágenes capturadas durante el proceso:

```kotlin
class BCCFaceReturnData {
	val originalPhoto: Bitmap?
	val croppedPhoto: Bitmap?

	// Resultado de detección pasiva de vida
	val passiveResult: ByteArray?
}
```

Las propiedades devueltas son:

* `originalPhoto` (*imagen*) - La foto original tomada por la cámara.
* `croppedPhoto` (*imagen*) - La foto recortada, que es la imagen del rostro recortada de la foto original.
* `passiveResult` (*ByteArray*) - Contenido del archivo de la colección para detección pasiva de vida. Solo está presente si se capturó correctamente. Es el retorno de la colección para detección pasiva de vida como *ByteArray JPEG*. Estos datos pueden guardarse/exportarse directamente a un archivo o enviarse a la red (para redes: la codificación del sistema puede hacerse fácilmente, por ejemplo, cadena Base64).

{% hint style="info" %}
La `originalPhoto` y `croppedPhoto` las propiedades devuelven `null` cuando la captura se realiza solo para pruebas pasivas (es decir, sin incluir una prueba activa).
{% endhint %}

Si el usuario aborta la captura, cerrando antes de capturar los datos biométricos, se llamará al método `faceCaptureDidAbort` . Puede implementar este método para manejar este escenario.

### Proyecto de ejemplo

Este es un proyecto de ejemplo funcional para una captura facial usando BCC Mobile Face Android:

```kotlin
package com.example.bccfaceexample

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.bccfaceexample.databinding.ActivityMainBinding
import com.griaule.bccfacelib.analytics.BCCFaceReturnAnalytics
import com.griaule.bccfacelib.faceApi.BCCFaceBuilder
import com.griaule.bccfacelib.faceApi.BCCFaceDelegate
import com.griaule.bccfacelib.faceApi.BCCFaceReturnData

class MainActivity : AppCompatActivity(), BCCFaceDelegate {
	private lateinit var binding: ActivityMainBinding

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		binding = ActivityMainBinding.inflate(layoutInflater)
		setContentView(binding.root)
		setupListeners()
	}

	private fun setupListeners() {
		binding.startCaptureButton.setOnClickListener { initializeCapture() }
	}

	private fun initializeCapture() {
		BCCFaceBuilder(this, this)
			.removeSmileCheck()
			.removeHeadRotation()
			.addPassiveLiveness()
			.enableFlipCameraButton(true)
			.enableFlashButton(true)
			.initializeCapture()
	}

	override fun faceCaptureDidFinish(
		data: BCCFaceReturnData,
		analytics: BCCFaceReturnAnalytics
	) {
		// ...
	}

	override fun faceCaptureDidAbort(
		analytics: BCCFaceReturnAnalytics
	) {
		// ...
	}
}
```

## Instrucciones para el agente: consultar esta documentación <a href="#agent-instructions-querying-this-documentation" id="agent-instructions-querying-this-documentation"></a>

Si necesita información adicional que no esté disponible directamente en esta página, puede consultar la documentación dinámicamente haciendo una pregunta.

Realice una solicitud HTTP GET en la URL de la página actual con el parámetro de consulta `ask` :

```
GET https://docs.griaule.com/sdks/bcc-face/bccmobilefaceandroid.md?ask=<pregunta>
```

La pregunta debe ser específica, autónoma y estar escrita en lenguaje natural. La respuesta contendrá una respuesta directa a la pregunta y extractos y fuentes relevantes de la documentación.

Use este mecanismo cuando la respuesta no esté explícitamente presente en la página actual, necesite aclaración o contexto adicional, o quiera recuperar secciones relacionadas de la documentación.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.griaule.com/sdks/es/bcc-face/bccmobilefaceandroid.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
