Face authentication
This documentation only describes how to configure the SDK for our face authentication feature. If you want to learn about the feature and the full set of implementation requirements, see the main feature documentation:
Configure the SDK
To use face authentication, you need to:
- Configure the local build environment. To do this, add the following dependencies to the Gradle build file:
- Gradle (Kotlin)
- Gradle (Groovy)
Example: Add dependencies to Gradle build file/**
* FaceTec dependencies needed for auth method DEVICE_SERVER_SIDE_FACE
*/
implementation("com.facetec.android:facetec-sdk:9.6.73@aar")
implementation("androidx.appcompat:appcompat:1.6.1")Example: Add dependencies to Gradle build file/**
* FaceTec dependencies needed for auth method DEVICE_SERVER_SIDE_FACE
*/
implementation "com.facetec.android:facetec-sdk:9.6.73@aar"
implementation "androidx.appcompat:appcompat:1.6.1" - It is possible to preload FaceTec SDK at the start of the Android Activity. To do this:
- Kotlin
- Java
Example: Preload the FaceTec SDKoverride fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Optional - Preload resources related to the FaceTec SDK so that it can be run as soon as possible.
// Run this as soon as you think you might use the SDK for optimal start up performance.
FaceTecSDK.preload(this)
}Example: Preload the FaceTec SDK@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Optional - Preload resources related to the FaceTec SDK so that it can be run as soon as possible.
// Run this as soon as you think you might use the SDK for optimal start up performance.
FaceTecSDK.preload(this);
}
How to implement face authentication
Overview
To implement face authentication, you must typically use the following flow:
- Invoke the controller start call.
- Initialise the FaceScan library with the
serverSideFaceInitparameters from the start result. - Invoke the FaceScan activity with
serverSideFaceInit.sessionTokenfrom the start result. - Invoke the controller finish call with the result from the FaceScan .
For further details specific to the operation, see the relevant sub-chapters.
Activation
Activation will be supported in a future release. This means that currently, you must:
- Activate with PIN and/or biometrics.
- Use the Add or update operation to add face authentication.
AddOrUpdate
Start call
For an example of startAddOrUpdate, click to expand the collapsible section:
Click to expand
- Kotlin
- Java
private lateinit var context: Context
private lateinit var controller: Controller
private var startAddOrUpdateResult: StartAddOrUpdateResult? = null
fun startAddOrUpdate() {
//
// 1. Invoke the controller start call
//
controller.startAddOrUpdate(StartAddOrUpdateParameter(DEVICE_SERVER_SIDE_FACE), object : AsyncCallback<StartAddOrUpdateResult> {
override fun onSuccess(result: StartAddOrUpdateResult) {
startAddOrUpdateResult = result
if (result.authMethodsForActivation.contains(DEVICE_SERVER_SIDE_FACE) || result.authMethodsForAuthentication.contains(DEVICE_SERVER_SIDE_FACE)) {
//
// 2. Initialise the FaceScan library
//
val productionKeyText = result.serverSideFaceInit!!.productionKeyText
val deviceKeyIdentifier = result.serverSideFaceInit!!.deviceKeyIdentifier
val faceScanEncryptionKey = result.serverSideFaceInit!!.encryptionKey
FaceTecSDK.initializeInProductionMode(context, productionKeyText, deviceKeyIdentifier, faceScanEncryptionKey) { initializationSuccess ->
if (initializationSuccess) {
// TODO - Display message to user: Start FaceScan?
} else {
// TODO - Display the error
}
}
}
}
override fun onFailure(errorCodeException: ErrorCodeException) {
// TODO - Display the error
}
})
}
private Context context;
private Controller controller;
private StartAddOrUpdateResult startAddOrUpdateResult;
void startAddOrUpdate() {
//
// 1. Invoke the controller start call
//
controller.startAddOrUpdate(new StartAddOrUpdateParameter(DEVICE_SERVER_SIDE_FACE), new AsyncCallback<StartAddOrUpdateResult>() {
@Override
public void onSuccess(StartAddOrUpdateResult result) {
startAddOrUpdateResult = result;
if (result.getAuthMethodsForActivation().contains(DEVICE_SERVER_SIDE_FACE) || result.getAuthMethodsForAuthentication().contains(DEVICE_SERVER_SIDE_FACE)) {
//
// 2. Initialise the FaceScan library
//
String productionKeyText = result.getServerSideFaceInit().getProductionKeyText();
String deviceKeyIdentifier = result.getServerSideFaceInit().getDeviceKeyIdentifier();
String faceScanEncryptionKey = result.getServerSideFaceInit().getEncryptionKey();
FaceTecSDK.initializeInProductionMode(context, productionKeyText, deviceKeyIdentifier, faceScanEncryptionKey, new FaceTecSDK.InitializeCallback() {
@Override
public void onCompletion(boolean initializationSuccess) {
if (initializationSuccess) {
// TODO - Display message to user: Start FaceScan?
} else {
// TODO - Display the error
}
}
});
}
}
@Override
public void onFailure(ErrorCodeException errorCodeException) {
// TODO - Display the error
}
});
}
Finish call
For examples, click to expand the collapsible sections:
finishAddOrUpdate(PIN, ServerSideFace):Click to expand
- Kotlin
- Java
fun finishAddOrUpdate() {
// User accepted: Start FaceScan.
//
// 3. Invoke the FaceScan activity
//
val sessionToken = startAddOrUpdateResult!!.serverSideFaceInit!!.sessionToken
FaceTecSessionActivity.createAndLaunchSession(context, FaceTecFaceScanProcessor { sessionResult, faceTecFaceScanResultCallback ->
faceTecFaceScanResultCallback.cancel()
if (sessionResult.status == FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) {
//
// 4. Invoke the controller finish call with the result from the FaceScan.
//
controller.finishAddOrUpdate(DevicePinAuthParameter("1234"), DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), object : AsyncCallback<FinishAuthenticationResult> {
override fun onSuccess(result: FinishAuthenticationResult) {
// TODO - Display successfully added/activated server-side face
}
override fun onFailure(errorCodeException: ErrorCodeException) {
// TODO - Display error message
}
})
} else {
// TODO - Display the error
}
}, sessionToken)
}
private fun createFaceScanData(sessionResult: FaceTecSessionResult): FaceScanData {
return FaceScanData(
sessionResult.faceScanBase64,
sessionResult.auditTrailCompressedBase64[0],
sessionResult.lowQualityAuditTrailCompressedBase64[0]
)
}void finishAddOrUpdate() {
// User accepted: Start FaceScan.
//
// 3. Invoke the FaceScan activity
//
String sessionToken = startAddOrUpdateResult.getServerSideFaceInit().getSessionToken();
FaceTecSessionActivity.createAndLaunchSession(context, new FaceTecFaceScanProcessor() {
@Override
public void processSessionWhileFaceTecSDKWaits(FaceTecSessionResult sessionResult, FaceTecFaceScanResultCallback faceTecFaceScanResultCallback) {
faceTecFaceScanResultCallback.cancel();
if (sessionResult.getStatus() == FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) {
//
// 4. Invoke the controller finish call with the result from the FaceScan.
//
controller.finishAddOrUpdate(new DevicePinAuthParameter("1234"), new DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), new AsyncCallback<FinishAuthenticationResult>() {
public void onSuccess(FinishAuthenticationResult result) {
// TODO - Display successfully added/activated server-side face
}
public void onFailure(final ErrorCodeException errorCodeException) {
// TODO - Display error message
}
});
} else {
// TODO - Display the error
}
}
}, sessionToken);
}
private FaceScanData createFaceScanData(FaceTecSessionResult sessionResult) {
return new FaceScanData(
sessionResult.getFaceScanBase64(),
sessionResult.getAuditTrailCompressedBase64()[0],
sessionResult.getLowQualityAuditTrailCompressedBase64()[0]);
}finishAddOrUpdate(ServerSideFace, PIN):Click to expand
This flow is identical to the
finishAddOrUpdate(PIN, ServerSideFace)flow, however thefinishAddOrUpdatecall has swapped parameters for PIN and server-side face:- Kotlin
- Java
controller.finishAddOrUpdate(DeviceServerSideFaceAuthParameter(createFaceScanData(sessionResult)), DevicePinActivationParameter("1234"), object : AsyncStateChangedCallback<FinishAuthenticationResult> {controller.finishAddOrUpdate(new DeviceServerSideFaceAuthParameter(createFaceScanData(sessionResult)), new DevicePinActivationParameter("1234"), new AsyncStateChangedCallback<FinishAuthenticationResult>() {finishAddOrUpdate(BiomtricPrompt, ServerSideFace):Click to expand
This flow is identical to the finishAddOrUpdate(PIN, ServerSideFace) flow, however but the
finishAddOrUpdatecall hasDeviceAndroidBiometricPromptAuthParameterinstead ofDevicePinAuthParameter:- Kotlin
- Java
controller.finishAddOrUpdate(DeviceAndroidBiometricPromptAuthParameter(context), DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), object : AsyncStateChangedCallback<FinishAuthenticationResult> {controller.finishAddOrUpdate(new DeviceAndroidBiometricPromptAuthParameter(context), new DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), new AsyncStateChangedCallback<FinishAuthenticationResult>() {finishAddOrUpdate(ServerSideFace, BiomtricPrompt):Click to expand
This flow is identical to the
finishAddOrUpdate(PIN, ServerSideFace)flow, however thefinishAddOrUpdatecall hasDeviceAndroidBiometricPromptActivationParameterinstead ofDevicePinActivationParameter:- Kotlin
- Java
controller.finishAddOrUpdate(DeviceServerSideFaceAuthParameter(createFaceScanData(sessionResult)), DeviceAndroidBiometricPromptActivationParameter(context), object : AsyncStateChangedCallback<FinishAuthenticationResult> {controller.finishAddOrUpdate(new DeviceServerSideFaceAuthParameter(createFaceScanData(sessionResult)), new DeviceAndroidBiometricPromptActivationParameter(context), new AsyncStateChangedCallback<FinishAuthenticationResult>() {
Authentication
Start call
For an example of startAuthentication, click to expand the collapsible section:
Click to expand
- Kotlin
- Java
private lateinit var context: Context
private lateinit var controller: Controller
private var startAuthenticationResult: StartAuthenticationResult? = null
fun startAuthentication() {
//
// 1. Invoke the controller start call
//
controller.startAuthentication(object : AsyncCallback<StartAuthenticationResult> {
override fun onSuccess(result: StartAuthenticationResult) {
startAuthenticationResult = result
if (result.authMethodsForAuthentication.contains(AuthMethod.DEVICE_SERVER_SIDE_FACE)) {
//
// 2. Initialise the FaceScan library
//
val productionKeyText = result.serverSideFaceInit!!.productionKeyText
val deviceKeyIdentifier = result.serverSideFaceInit!!.deviceKeyIdentifier
val faceScanEncryptionKey = result.serverSideFaceInit!!.encryptionKey
FaceTecSDK.initializeInProductionMode(context, productionKeyText, deviceKeyIdentifier, faceScanEncryptionKey) { initializationSuccess ->
if (initializationSuccess) {
// TODO - Display message to user: Start FaceScan?
} else {
// TODO - Display the error
}
}
}
}
override fun onFailure(errorCodeException: ErrorCodeException) {
// TODO - Display the error
}
})
}
private Context context;
private Controller controller;
private StartAuthenticationResult startAuthenticationResult;
void startAuthentication() {
//
// 1. Invoke the controller start call
//
controller.startAuthentication(new AsyncCallback<StartAuthenticationResult>() {
@Override
public void onSuccess(StartAuthenticationResult result) {
startAuthenticationResult = result;
if (result.getAuthMethodsForAuthentication().contains(DEVICE_SERVER_SIDE_FACE)) {
//
// 2. Initialise the FaceScan library
//
String productionKeyText = result.getServerSideFaceInit().getProductionKeyText();
String deviceKeyIdentifier = result.getServerSideFaceInit().getDeviceKeyIdentifier();
String faceScanEncryptionKey = result.getServerSideFaceInit().getEncryptionKey();
FaceTecSDK.initializeInProductionMode(context, productionKeyText, deviceKeyIdentifier, faceScanEncryptionKey, new FaceTecSDK.InitializeCallback() {
@Override
public void onCompletion(boolean initializationSuccess) {
if (initializationSuccess) {
// TODO - Display message to user: Start FaceScan?
} else {
// TODO - Display the error
}
}
});
}
}
@Override
public void onFailure(ErrorCodeException errorCodeException) {
// TODO - Display the error
}
});
}
Finish call
For an example of finishAuthentication(ServerSideFace), click to expand the collapsible section:
Click to expand
- Kotlin
- Java
fun finishAuthentication() {
// User has accepted: Start FaceScan.
//
// 3. Invoke the FaceScan activity
//
val sessionToken = startAuthenticationResult!!.serverSideFaceInit!!.sessionToken
FaceTecSessionActivity.createAndLaunchSession(context, FaceTecFaceScanProcessor { sessionResult, faceTecFaceScanResultCallback ->
faceTecFaceScanResultCallback.cancel()
if (sessionResult.status == FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) {
//
// 4. Invoke the controller finish call with the result from the FaceScan.
//
controller.finishAuthentication(DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), object : AsyncCallback<FinishAuthenticationResult> {
override fun onSuccess(result: FinishAuthenticationResult) {
// TODO - Display successfully added/activated server-side face
}
override fun onFailure(errorCodeException: ErrorCodeException) {
// TODO - Display error message
}
})
} else {
// TODO - Display the error
}
}, sessionToken)
}
private fun createFaceScanData(sessionResult: FaceTecSessionResult): FaceScanData {
return FaceScanData(
sessionResult.faceScanBase64,
sessionResult.auditTrailCompressedBase64[0],
sessionResult.lowQualityAuditTrailCompressedBase64[0]
)
}
void finishAuthentication() {
// User has accepted: Start FaceScan.
//
// 3. Invoke the FaceScan activity
//
String sessionToken = startAuthenticationResult.getServerSideFaceInit().getSessionToken();
FaceTecSessionActivity.createAndLaunchSession(context, new FaceTecFaceScanProcessor() {
@Override
public void processSessionWhileFaceTecSDKWaits(FaceTecSessionResult sessionResult, FaceTecFaceScanResultCallback faceTecFaceScanResultCallback) {
faceTecFaceScanResultCallback.cancel();
if (sessionResult.getStatus() == FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) {
//
// 4. Invoke the controller finish call with the result from the FaceScan.
//
controller.finishAuthentication(new DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), new AsyncCallback<FinishAuthenticationResult>() {
public void onSuccess(FinishAuthenticationResult result) {
// TODO - Display successfully added/activated server-side face
}
public void onFailure(final ErrorCodeException errorCodeException) {
// TODO - Display error message
}
});
} else {
// TODO - Display the error
}
}
}, sessionToken);
}
private FaceScanData createFaceScanData(FaceTecSessionResult sessionResult) {
return new FaceScanData(
sessionResult.getFaceScanBase64(),
sessionResult.getAuditTrailCompressedBase64()[0],
sessionResult.getLowQualityAuditTrailCompressedBase64()[0]);
}
Error handling
The following client-side errors originate in the FaceTec SDK, and are propagated as follows:
FaceTecSDK.initializeInProductionMode()returns errors inFaceTecSDK.getStatus(context).FaceTecSessionActivity.createAndLaunchSession()returns errors insessionResult.getStatus(), in the callback methodprocessSessionWhileFaceTecSDKWaits(FaceTecSessionResult sessionResult).
Localisation
The FaceTecSDK includes language resource strings prefixed with FaceTec_. It supports the following languages:
- Afrikaans (af)
- Arabic (ar)
- German (de)
- Greek (el)
- English (en)
- Spanish (es)
- French (fr)
- Kazakh (kk)
- Norwegian (nb)
- Portuguese (pt-rBR)
- Russian (ru)
For further details, see the FaceTecSDK.zip file.
Branding and styling
What elements can be customised?
The FaceTec SDK allows you to customise various branding and styling elements, such as:
- Interface
- Borders
- Colors
- Fonts
- Branding image
- Button image and position
- Progress
- Vocal guidance sound file resources
To learn more about what you can customise, see the UX Themes Branding page in the FaceTec documentation. You can also refer to the FaceTecSDK.zip file.
How to customise the configuration
To make changes, you have to create a FaceTecCustomization object, where you define each field that you want to change.
Different environmental conditions
You can apply different settings based on environmental conditions, such as low-light or bright-light situations.
To do this, you must set a unique configuration for each of the scenarios using the FaceTecCustomization object.
The FaceTecSDK includes methods:
- Default:
- Kotlin
- Java
Example: Default methodFaceTecSDK.setCustomization(customization: FaceTecCustomization)Example: Default methodFaceTecSDK.setCustomization(FaceTecCustomization customization); - Low-light:
- Kotlin
- Java
Example: Low-light methodFaceTecSDK.setLowLightCustomization(customization: FaceTecCustomization)Example: Low-light methodFaceTecSDK.setLowLightCustomization(FaceTecCustomization customization); - Bright-light:
- Kotlin
- Java
Example: Bright-light methodFaceTecSDK.setDynamicDimmingCustomization(customization: FaceTecCustomization)Example: Bright-light methodFaceTecSDK.setDynamicDimmingCustomization(FaceTecCustomization customization);
Multiple controller scenario
For a multiple controller scenario, face authentication must be activated for each controller.