> For the complete documentation index, see [llms.txt](https://docs.griaule.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.griaule.com/sdks/en/bcc-face/bccmobilefaceandroid.md).

# Android

**BCC Face** is an Android library intended to be integrated into an Android application.

It uses the device camera to take a photo of a face for biometric purposes. It provides a simple active liveness test, requiring the person to smile for about one second and/or look to the right or left. The liveness test includes an option to play the instructions by voice, making the flow easier for users. In addition, it provides a passive liveness test that can be used to verify that the photo was taken of a real person without requiring user interaction.

This manual is up to date for BCC Face Mobile Android version `4.12.2`.

{% hint style="warning" %}
The **passive liveness test** is only available from version `4.4.0` onwards.
{% endhint %}

### Requirements

**BCC Face** is an Android library and must be imported into the target project.

* Minimum Android version: *Android 6.0 (SDK 23), "Marshmallow"*.
* The mobile device must have a camera.
* The native application must be built with Android technology.
* Development environment: an Android IDE is required, such as [Android Studio](https://developer.android.com/studio) (recommended).
* Additional external dependencies:
  * [Google ML Kit](https://developers.google.com/ml-kit/guides), face detection version 16.1.7;
  * [Lottie](https://lottiefiles.com), version 3.0.0;
  * [RootBeer](https://github.com/scottyab/rootbeer), version 0.1.1;
  * [Gson](https://github.com/google/gson), version 2.8.5;
  * [Google Tink](https://github.com/tink-crypto), version 1.11.0;
  * [Material Components](https://github.com/material-components/material-components-android), version 1.6.1.
* External services:
  * Firebase, by Google. An account is required, but no charges will apply since the library only uses on-device APIs.

### Installation

#### Adding the Library to the App Project

BCC Face is provided by Griaule as an `.aar` file.

To add the libraries, go to your project directory, open the **app** folder and create the directories: `libs/bccface`. Then add the `bccfacelib-release.aar` dependency. The folder structure should look similar to this:

![](https://3411546999-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5TVzatVMAV3OF5tyA1VF%2Fuploads%2Fgit-blob-c549379fb9b16f47f9db997405fe4476d8ed1014%2FfaceFolderStructre.png?alt=media)

The next step is to make these files visible to the Gradle dependencies. To do so, add the following line to the `build.gradle (:app)` file, inside the dependencies object:

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

Inside the `build.gradle (:app)` file, also add the compile options and set Source Compatibility and Target Compatibility to use 1.8 (Java 8):

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

#### Configuring Google ML Kit

It is recommended to follow the instructions provided in "[Option 1: Use the Firebase console setup workflow](https://firebase.google.com/docs/android/setup#console)" from the Firebase for Android documentation: [Add Firebase to your Android project](https://firebase.google.com/docs/android/setup).

An account is required, but no charges will apply since the library only uses on-device APIs: [See Firebase pricing details](https://firebase.google.com/pricing/).

If [Option 1](https://firebase.google.com/docs/android/setup#console) was chosen, make sure to generate the `google-services.json` file and place it in the `android/app/` directory.

Make changes to the following files:

* `android/build.gradle`

```groovy
  buildscript {
  	// ...
  	dependencies {
  		// ...
  		classpath 'com.google.gms:google-services:4.4.2'
  	}
  }
```

* `android/app/build.gradle`, add to the end of the file:

```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'
  	// Add the line above if using analytics
  }
```

#### Configuring All Dependencies

Make changes to the following files:

* `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'
  }
```

### Usage

#### Parameters and Constructor

To use the BCC Face library correctly, there are some mandatory parameters.

A simple example of using the library is shown below:

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

***

`BCCFaceBuilder` is the class constructor and receives the following parameters:

* `context: Context` - The application context.
* `delegate: BCCFaceDelegate` - Interface responsible for notifying capture events (for example, failure or success).

***

`BCCFaceBuilder` is the class responsible for controlling the usage configuration of `BCCFace`. The following parameters are accepted to configure the biometric capture and the software behavior:

* `buildSmileCheck(smileProbability: Float = 0.8f)` - Adds the smile to the liveness test and sets the acceptance threshold. This feature is enabled by default.
* `removeSmileCheck()` - Removes the smile from the liveness test.
* `buildRotationCheck(livenessConfigList: List<HeadRotationCheck>, headRotationAngle: Float = 20f)` - Defines a list of head rotation liveness tests and the maximum rotation angle. This feature is enabled by default. The head rotation options are:

```kotlin
  enum class HeadRotationCheck {
  	randomRotation,
  	leftRotation,
  	rightRotation;
  }
```

* `removeHeadRotation()` - Removes head rotation from the liveness test.
* `addPassiveLiveness()` - Adds the passive liveness test. This feature is used to verify that the captured photo is of a real person without requiring any user interaction. To use only this feature, the active liveness tests (`removeSmileCheck()` and `removeHeadRotation()`), which are enabled by default, must be disabled. It is also possible to combine both types of test, using passive and active liveness simultaneously.
* `buildSpeechSettings(speechSettings: SpeechSettings?)` - Defines the criteria for accessibility speech, using the following parameters:

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

* `volume` - The audio volume between `0.0` and `1.0`.
* `startsMuted` - Defines whether the instructions start muted or not (`true` for muted).
* `pitch` - Defines the voice pitch for the instructions between `0.5` (low) and `2.0` (high).
* `speed` - Defines the voice speed for the instructions. This value must be positive.

The preset values can be accessed through the static variable:

```groovy
  class SpeechSettings {
  	companion object {
  		val defaultSpeechSettings = SpeechSettings()
  	}
  }
```

* `removeSpeech()` - Removes accessibility speech.
* `setInstructionEnable(enable: Boolean)` - Defines whether the instructions screen is enabled or disabled.
* `forceLanguage(language: BCCFaceAPI.BCCLanguages?)` - Forces the instructions to be displayed in a single language. If the device language is not supported, English will be used. The supported languages are:

```kotlin
  enum class BCCLanguages(val locale: Locale) {
  	ptBR(Locale("pt", "br")),
  	enUS(Locale.US),
  	esMX(Locale("es", "mx")),
  	deviceLanguage(Locale.getDefault());
  }
```

* `removeLanguage()` - Removes the forced language.
* `enableFlipCameraButton(enable: Boolean)` - Enables (`true`) or disables (`false`) the camera flip button (front or rear camera). Default: enabled (`true`).
* `enableFlashButton(enable: Boolean)` - Enables (`true`) or disables (`false`) the flash button on the rear camera. Default: disabled (`false`).
* `enableManualCapture(enable: Boolean)` - Enables (`true`) or disables (`false`) the manual capture button, which allows bypassing the automatic capture checks. When performing a manual capture, the user will be able to review the captured photo before finishing the process.
* `enableIntegrityValidation(clientSecret: ByteArray, nonce: ByteArray)` - Enables integrity validation for passive liveness, an extra layer of security to ensure the integrity of the payload.
* `setImageCompressionFormat(format: ImageCompressionFormat)` - Defines the compression format of a passive liveness capture. You can choose between `ImageCompressionFormat.JPEG` (default) or `ImageCompressionFormat.JPEG200`
* `setCameraInitialDirection(CameraFacingDirection.<FRONT or BACK>)` - Defines the initial camera direction; choose between:
  * `CameraFacingDirection.FRONT` - Front camera (default setting).
  * `CameraFacingDirection.BACK` - Rear camera.

***

All camera direction settings are achieved by combining the `enableFlipCameraButton` and `setCameraInitialDirection` methods. For example:

* Start with the front camera and enable the camera flip button:

```kotlin
  BCCFaceBuilder(this, this)
  	.enableFlipCameraButton(true)
  	.setCameraInitialDirection(CameraFacingDirection.FRONT)
```

* Start with the rear camera and disable the camera flip button:

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

***

For reference, here is the complete list of parameters and default values:

```kotlin
var showInstructionScreen: Boolean = false,
var stopVerifyEyesOpenTimeout: Long = 20,   // Deprecated as of 4.12.2
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" %}
The active liveness test (using smile and random head rotation) is enabled by default. To use only the passive liveness test, before adding it, you must remove the active liveness methods from the builder:

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

{% endhint %}

Here is a code snippet to initialize a capture using only the passive liveness test:

```kotlin
// From the desired Activity...

// Create the builder
BCCFaceBuilder faceBuilder = new BCCFaceBuilder(this, this);

// Configure the builder
faceBuilder
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness();

// Initialize the capture from the builder
faceBuilder.initializeCapture();
```

#### Return Values

The results of the last face capture can be retrieved using the `faceCaptureDidFinish` method of the `BCCFaceDelegate` interface:

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

The `data` object contains both images captured during the process:

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

	// Passive Liveness Result
	val passiveResult: ByteArray?
}
```

The returned properties are:

* `originalPhoto` (*image*) - The original photo taken by the camera.
* `croppedPhoto` (*image*) - The cropped photo, which is the face image cropped from the original photo.
* `passiveResult` (*ByteArray*) - File content of the passive liveness collection. It is only present if captured successfully. It is the return of the passive liveness collection as a *JPEG ByteArray* or *JPEG 2000*. This data can be saved/exported directly to a file or sent over the network (for network transmission, the data can easily be encoded, e.g., as a Base64 string).

{% hint style="info" %}
The `originalPhoto` and `croppedPhoto` properties return `null` when the capture is performed for passive tests only (i.e., without including an active test).
{% endhint %}

If the user aborts the capture or if any failure occurs during the process, the `faceCaptureDidAbort` method will be called. You can implement this method to handle this scenario.

#### Sample Project

This is a working sample project for face capture using 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
	) {
		// ...
	}
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
