Guia de uso SDK BioTrust - Android
Este guia fornece instruções detalhadas para integrar o BiometricFaceValidator SDK em aplicações Android.
:::tip Pré-requisitos
- Android 7.0 (API 24) ou superior
- Android Studio 4.0 ou superior
- Dispositivo físico (não funciona no Emulador)
- Câmera frontal funcional :::
:::tip Exemplo
- Faça download da aplicação exemplo do SDK BioTrust
- https://github.com/biotrust-io/BioTrust-Example-Android :::
Instalação
Gradle
Adicione no build.gradle do módulo (app):
dependencies {
//Gradle
implementation group: 'io.biotrust', name: 'biometricfacevalidator', version: '1.0.5'
//Gradle (Short)
implementation 'io.biotrust:biometricfacevalidator:1.0.5'
//Gradle (Kotlin)
implementation("io.biotrust:biometricfacevalidator:1.0.5")
}
Permissões
Adicione no AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<suses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Requer câmera física -->
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<suses-feature
android:name="android.hardware.camera.front"
android:required="true" />
ProGuard
Se usando ProGuard, adicione no proguard-rules.pro:
-keep class io.biotrust.biometricfacevalidator.** { *; }
-keep class io.biotrust.biometricfacevalidator.model.** { *; }
Configuração Básica
Importações
import androidx.compose.ui.tooling.preview.Preview;
import androidx.camera.core.ExperimentalGetImage;
import io.biotrust.biometricfacevalidator.BiometricValidationLauncher;
import io.biotrust.biometricfacevalidator.FaceBiometricConfig;
import io.biotrust.biometricfacevalidator.model.ValidationMode;
import io.biotrust.biometricfacevalidator.model.ValidationResult;
Criando a Configuração
O FaceBiometricConfig é criado usando o padrão Builder:
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setUuid("seu-uuid-aqui")
.setApiUrl("https://api.biotrust.io")
.setValidationMode(ValidationMode.LIVENESS_ONLY)
.build();
Parâmetros de Configuração
Parâmetros Obrigatórios
| Parâmetro | Tipo | Descrição |
|---|---|---|
setUuid() | String | Identificador único do usuário |
setApiUrl() | String | URL da API de validação |
setValidationMode() | ValidationMode | Modo de validação |
Parâmetros Opcionais
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
setChallengeCount() | int | 3 | Número de desafios (1-5) |
setRequireAllChallenges() | boolean | true | Se todos os desafios são obrigatórios |
setTimeout() | long | 30000 | Timeout em milissegundos |
setFaceDetectionTimeOutMS() | int | 30000 | Timeout para detecção de rosto |
setMaxIncorrectChallengeAttemps() | int | 15 | Máximo de tentativas incorretas |
setLocale() | String | null | Idioma ("en", "pt-BR", "es-ES") |
setThemeMode() | String | null | Tema ("light", "dark", "system") |
setDocumentInfo() | DocumentInfo | null | Informações do documento (obrigatório para .LIVENESS_WITH_DOCUMENT) |
Modos de Validação
public enum ValidationMode {
LIVENESS_ONLY, // Apenas prova de vida
LIVENESS_WITH_DOCUMENT, // Prova de vida + validação contra o CPF
FACE_MATCH, // Prova de vida + busca 1:N na base cadastrada
FACE_MATCH_EXACT // Prova de vida + conferência 1:1 contra um documento
}
Informações do Documento
Para validação com documento, crie um DocumentInfo:
// Criar data de nascimento
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
Date birthDate = sdf.parse("01/01/1990");
// Criar informações do documento
DocumentInfo documentInfo = new DocumentInfo(
"12345678901", // CPF
birthDate // Data de nascimento
);
Exemplo de Implementação
Criando o Launcher
public class MainActivity extends AppCompatActivity {
private BiometricValidationLauncher launcher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Implementando o Callback
O callback deve implementar a interface ValidationResultCallback com o método unificado onValidationComplete:
private class MyValidationCallback implements BiometricValidationLauncher.ValidationResultCallback {
@Override
public void onValidationComplete(ValidationResult result) {
if (result.isSuccess()) {
Log.d("Validation", "Validação bem-sucedida: " + result.getMessage());
// Verificar se é validação com documento ou apenas liveness
if (result.getDocumentResult() != null) {
// Validação com documento
DocumentValidationResult docResult = result.getDocumentResult();
Log.d("Validation", "Nome: " + docResult.getFullName());
Log.d("Validation", "CPF: " + docResult.getDocument());
Log.d("Validation", "Data Nascimento: " + docResult.getDateOfBirth());
Log.d("Validation", "Similaridade: " + docResult.getFacialBiometrics().getSimilarity() + "%");
Log.d("Validation", "Disponível: " + docResult.getFacialBiometrics().isAvailable());
Log.d("Validation", "Probabilidade: " + docResult.getFacialBiometrics().getProbability());
} else {
// Validação apenas de liveness
Log.d("Validation", "Validação de liveness concluída");
}
// Confiança de vivacidade (disponíevl para ambos os modos)
Log.d("Validation", "Confiança de vivacidade: " + Math.round(result.getVivacityConfidence() * 100));
// Imagem capturada (disponível para ambos os modos)
if (result.getFaceBitmap() != null) {
Log.d("Validation", "Imagem capturada: " +
result.getFaceBitmap().getWidth() + "x " + result.getFaceBitmap().getHeight());
}
} else {
// Falha na validação
Log.e("Validation", "Validação falhou: " + result.getMessage());
}
}
}
Iniciando a Validação
Validação de Vivacidade Apenas
private void startLivenessValidation() {
// Criar configuração
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setUuid("seu-uuid-aqui")
.setApiUrl("https://api.biotrust.io")
.setValidationMode(ValidationMode.LIVENESS_ONLY)
.setLocale("pt-BR")
.setChallengeCount(3)
.build();
// Criar callback
MyValidationCallback callback = new MyValidationCallback();
// Criar launcher
launcher = new BiometricValidationLauncher(
this, // Activity
callback, // Callback
config // Configuração
);
// Iniciar validação
launcher.launch(this);
}
Validação com Documento
private void startDocumentValidation() {
try {
// Criar informações do documento
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
Date birthDate = sdf.parse("01/01/1990");
DocumentInfo documentInfo = new DocumentInfo(
"12345678901", // CPF
birthDate // Data de nascimento
);
// Criar configuração
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setUuid("seu-uuid-aqui")
.setApiUrl("https://api.biotrust.io")
.setValidationMode(ValidationMode.LIVENESS_WITH_DOCUMENT)
.setDocumentInfo(documentInfo)
.setLocale("pt-BR")
.setChallengeCount(3)
.build();
// Criar callback
MyValidationCallback callback = new MyValidationCallback();
// Criar launcher
launcher = new BiometricValidationLauncher(
this, // Activity
callback, // Callback
config // Configuração
);
// Iniciar validação
launcher.launch(this);
} catch (ParseException e) {
Log.e("Validation", "Erro ao converter data: " + e.getMessage());
}
}
FaceMatch (Reconhecimento 1:N)
Além da prova de vida, o SDK identifica quem é a pessoa comparando o rosto com a sua própria base cadastrada. São dois passos: cadastrar pessoas na base e depois buscar/conferir.
Buscar na base (FACE_MATCH)
Roda a prova de vida e procura o rosto entre todos os cadastros, retornando o mais parecido com o score de similaridade.
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setUuid("seu-uuid-aqui")
.setApiUrl("https://api.biotrust.io")
.setValidationMode(ValidationMode.FACE_MATCH)
.build();
BiometricValidationLauncher launcher =
new BiometricValidationLauncher(this, new MyValidationCallback(), config);
launcher.launch(this);
O resultado chega no callback em onFaceMatchComplete(...) (veja ValidationResult), com match, uniqueID, fullName, document e similarity.
Conferir contra um documento (FACE_MATCH_EXACT)
Verifica se o rosto bate com um cadastro específico. Exige um FaceMatchConfig com o documento.
FaceMatchConfig fmConfig = new FaceMatchConfig.Builder()
.setDocument("12345678901")
.build();
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setUuid("seu-uuid-aqui")
.setApiUrl("https://api.biotrust.io")
.setValidationMode(ValidationMode.FACE_MATCH_EXACT)
.setFaceMatchConfig(fmConfig)
.build();
new BiometricValidationLauncher(this, new MyValidationCallback(), config).launch(this);
Cadastro e gestão de pessoas
O cadastro (com captura + prova de vida) é feito pelo FaceMatchManagerLauncher.
FaceMatchManagerConfig managerConfig = new FaceMatchManagerConfig.Builder()
.setUuid("seu-uuid-aqui")
.setApiUrl("https://api.biotrust.io")
.build();
FaceMatchManagerLauncher manager =
new FaceMatchManagerLauncher(this, managerCallback, managerConfig);
// documentType: constante do tipo de documento (ex.: DocumentType.CPF)
manager.addPerson(this, "12345678901", "Maria Silva", DocumentType.CPF);
Também estão disponíveis editPerson(...) para atualizar um cadastro existente. O resultado de cada operação chega no FaceMatchManagerCallback.
Cadastre uma vez e depois reconheça sempre — ótimo para controle de acesso, portaria/condomínio, check-in de eventos e deduplicação/antifraude.
Resultados da Validação
ValidationResult
O ValidationResult contém todas as informações da validação de forma unificada:
public class ValidationResult {
public boolean isSuccess() // Se a validação foi bem-sucedida
public String getMessage() // Mensagem de retorno
public Bitmap getFaceBitmap() // Imagem do rosto capturada
public DocumentValidationResult getDocumentResult() // Resultado do documento (null para liveness apenas)
public boolean hasDocumentValidation() // Se inclui validação de documento
public Float getVivacityConfidence() // Confiança de vivacidade (0.0-1.0)
public ValidationMode getValidationMode() // Modo de validação usado
}
DocumentValidationResult
O DocumentValidationResult contém as informações do documento (apenas para validação com documento):
public class DocumentValidationResult {
public String getDocument() // CPF
public String getFullName() // Nome completo
public String getDateOfBirth() // Data de nascimento
public FacialBiometrics getFacialBiometrics() // Dados biométricos
public boolean isSuccess() // Se a validação foi bem-sucedida
// Classe interna para dados biométricos
public static class FacialBiometrics {
public String getLiveness() // Resultado de vivacidade
public boolean isAvailable() // Se o documento está disponível
public String getProbability() // Probabilidade
public float getSimilarity() // Percentual de similaridade
}
}
Personalização
Tema e Idioma
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setLocale("pt-BR") // "en", "pt-BR", "es-ES"
.setThemeMode("dark") // "light", "dark", "system"
.build();
Configurações Avançadas
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setChallengeCount(5) // Número de desafios (1-5)
.setRequireAllChallenges(false) // Se todos os desafios são obrigatórios
.setTimeout(60000L) // Timeout em milissegundos (60s)
.setFaceDetectionTimeOutMS(30000) // Timeout para detecção de rosto (30s)
.setMaxIncorrectChallengeAttemps(20) // Máximo de tentativas incorretas
.build();
Utilidades do Launcher
O BiometricValidationLauncher possui métodos para configuração dinâmica:
// Configurar locale
launcher.setLocale("en");
// Configurar tema
launcher.setThemeMode("light");
// Configurar modo de validação
launcher.setValidationMode(ValidationMode.LIVENESS_WITH_DOCUMENT);
// Configurar informações do documento
DocumentInfo documentInfo = new DocumentInfo("12345678901", new Date());
launcher.setDocumentInfo(documentInfo);
// Configurar UUID
Launcher.setUuid("novo-uuid");
// Configurar API URL
Launcher.setAPIUrl("https://api.biotrust.io");
// Obter valores atuais
String currentLocale = launcher.getLocale();
String currentTheme = launcher.getThemeMode();
ValidationMode currentMode = launcher.getValidationMode();
String currentUuid = launcher.getUuid();
String currentApiUrl = launcher.getAPIUrl();
Métodos Estáticos
O BiometricValidationLauncher fornece métodos estáticos úteis:
// Obter ID do dispositivo
String deviceId = BiometricValidationLauncher.getDeviceId();
// Obter versão do SDK
String sdkVersion = BiometricValidationLauncher.getSdkVersion();
// Obter nível da API Android
int apiLevel = BiometricValidationLauncher.getApiLevel();
Tratamento de Erros
:::danger Erros Comuns Verifique sempre se as configurações estão corretas antes de iniciar a validação :::
Erros de Configuração
try {
FaceBiometricConfig config = new FaceBiometricConfig.Builder()
.setUuid("uuid")
.setApiUrl("api-url")
.setValidationMode(ValidationMode.LIVENESS_WITH_DOCUMENT)
// Erro: DocumentInfo é obrigatório para este modo
// .setDocumentInfo(documentInfo)
.build();
} catch (IllegalArgumentException e) {
Log.e("Config", "Erro de configuração: " + e.getMessage());
}
Erros de Permissão
private void checkPermissions() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestuermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_PERMISSION_REQUEST_CODE);
} else {
// Permissão concedida, iniciar validação
startValidation();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permissão concedida
startValidation();
} else {
// Permissão negada
Log.e("Permission", "Permissão de câmera negada");
}
}
}
Exemplo Completo
package com.example.biometricapp;
import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import io.biotrust.biometricfacevalidator.BiometricValidationLauncher;
import io.biotrust.biometricfacevalidator.FaceBiometricConfig;
import io.biotrust.biometricfacevalidator.model.DocumentInfo;
import io.biotrust.biometricfacevalidator.model.DocumentValidationResult;
import io.biotrust.biometricfacevalidator.model.ValidationMode;
import io.biotrust.biometricfacevalidator.model.ValidationResult;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static final int CAMERA_PERMISSION_REQUEST_CODE = 100;
private BiometricValidationLauncher launcher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnLiveness = findViewById(R.id.btn_liveness);
Button btnDocument = findViewById(R.id.btn_document);
btnLiveness.setOnClickListener(v -> checkPermissionsAndStart(false));
btnDocument.setOnClickListener(v -> checkPermissionsAndStart(true));
}
private void checkPermissionsAndStart(boolean includeDocument) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_PERMISSION_REQUEST_CODE);
} else {
startValidation(includeDocument);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startValidation(false); // Iniciar com liveness apenas
} else {
Toast.makeText(this, "Permissão de câmera necessária", Toast.LENGTH_LONG).show();
}
}
}
private void startValidation(boolean includeDocument) {
try {
FaceBiometricConfig.Builder configBuilder = new FaceBiometricConfig.Builder()
.setUuid("seu-uuid-aqui")
.setApiUrl("https://api.biotrust.io")
.setLocale("pt-BR")
.setChallengeCount(3);
if (includeDocument) {
// Configuração para validação com documento
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
Date birthDate = sdf.parse("01/01/1990");
DocumentInfo documentInfo = new DocumentInfo(
"12345678901", // CPF
birthDate // Data de nascimento
);
configBuilder
.setValidationMode(ValidationMode.LIVENESS_WITH_DOCUMENT)
.setDocumentInfo(documentInfo);
} else {
// Configuração para validação de vivacidade apenas
configBuilder.setValidationMode(ValidationMode.LIVENESS_ONLY);
}
FaceBiometricConfig config = configBuilder.build();
// Criar callback unificado
MyValidationCallback callback = new MyValidationCallback();
// Criar launcher
launcher = new BiometricValidationLauncher(
this, // Activity
callback, // Callback
config // Configuração
);
// Iniciar validação
launcher.launch(this);
} catch (ParseException e) {
Log.e("Validation", "Erro ao converter data: " + e.getMessage());
Toast.makeText(this, "Erro ao configurar data", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e("Validation", "Erro geral: " + e.getMessage());
Toast.makeText(this, "Erro ao iniciar validação", Toast.LENGTH_SHORT).show();
}
}
private class MyValidationCallback implements BiometricValidationLauncher.ValidationResultCallback {
@Override
public void onValidationComplete(ValidationResult result) {
if (result.isSuccess()) {
Log.d("Validation", "Validação bem-sucedida: " + result.getMessage());
Toast.makeText(MainActivity.this, "Validação bem-sucedida!", Toast.LENGTH_SHORT).show();
// Verificar se é validação com documento ou apenas liveness
if (result.getDocumentResult() != null) {
// Validação com documento
DocumentValidationResult docResult = result.getDocumentResult();
Log.d("Validation", "Nome: " + docResult.getFullName());
Log.d("Validation", "CPF: " + docResult.getDocument());
Log.d("Validation", "Similaridade: " + docResult.getFacialBiometrics().getSimilarity() + "%");
Log.d("Validation", "Disponível: " + docResult.getFacialBiometrics().isAvailable());
} else {
// Validação apenas de liveness
Log.d("Validation", "Validação de liveness concluída");
}
// Dados disponíveis para ambos os modos
Log.d("Validation", "Confiança de vivacidade: " + result.getVivacityConfidence());
if (result.getFaceBitmap() != null) {
Log.d("Validation", "Imagem capturada: " +
result.getFaceBitmap().getWidth() + "x " + result.getFaceBitmap().getHeight());
}
} else {
// Falha na validação
Log.e("Validation", "Validação falhou: " + result.getMessage());
Toast.makeText(MainActivity.this, "Validação falhou: " + result.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
}
Exemplo de callback
private class NewValidationCallback implements BiometricValidationLauncher.ValidationResultCallback {
@Override
public void onValidationComplete(ValidationResult result) {
if (result.isSuccess()) {
// Sucesso - funciona para ambos os modos
if (result.getDocumentResult() != null) {
// Validação com documento
} else {
// Validação apenas de liveness
}
} else {
// Falha ou erro
}
}
}
Próximos Passos
Agora que você tem uma implementação funcional do BiometricFaceValidator SDK para Android, considere:
- Guia iOS — o mesmo fluxo no iOS
- Guia Web — integração no navegador
- App de exemplo (GitHub) — projeto completo funcionando
- Playground — teste a validação ao vivo
:::tip Dúvidas ou Suporte? Se você tiver dúvidas ou precisar de suporte, entre em contato com nossa equipe de desenvolvimento. :::