Fortface SDK Integration in Your Android App
How does it work?
Our SDK is designed to perform the Capture and/or Upload of the file of the document photo that will be sent to our Fortface API. It is independent of the app’s flow into which it will be integrated. It has its own isolated Activity that can be launched at any time by an Engine. Immediately after processing, the tool is automatically terminated.
Our SDK does not communicate directly with the Fortface API; see the communication flow below:

Below are the instructions for integrating our SDK, the process flow to correctly access our service, and a step-by-step guide on how to build an Engine.
Installation
Requirement
1. Platform Configuration
Android
It is currently possible to use the Fortface SDK in applications that support Android 6 - SDK 24 as the minimum version. However, by doing so, the developer gives up important security features of the tool, thereby assuming risks of attacks during captures.
Kotlin
Minimum version: 1.7.20
Installation
1. Add access to the Maven repository to your project
First you need to configure access to the Maven repository in your project. The artifact is served via CDN, with HTTP header authentication. Include the following block in repositories (for example in the app module’s build.gradle / build.gradle.kts, or in settings.gradle / settings.gradle.kts if your project uses dependencyResolutionManagement).
- Groovy
- Kotlin
repositories {
maven {
url "https://cdn-fortface-sdk.fortface.com.br"
credentials(HttpHeaderCredentials) {
name = "X-Sdk"
value = "ACCOUNT_NAME"
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
repositories {
maven {
url = uri("https://cdn-fortface-sdk.fortface.com.br")
credentials(HttpHeaderCredentials::class) {
name = "X-Sdk"
value = "ACCOUNT_NAME"
}
authentication {
create<HttpHeaderAuthentication>("header")
}
}
}
Replace ACCOUNT_NAME with the account identifier provided by our team.
Depending on your project configuration, you may need to declare the same repository in
settings.gradle/settings.gradle.kts(for example insidedependencyResolutionManagement { repositories { ... } }).
2. Configure Gradle
With the repository configured, you need to enable viewBinding and add the dependency for our SDK. Below you can find the changes to be added to your app's Gradle file:
- Groovy
- Kotlin
android {
...
buildFeatures {
viewBinding true
}
}
dependencies {
implementation (group: 'br.com.fortface', name: 'fortface', version:'1.19.2', ext: 'aar', classifier: 'release'){
transitive = true
}
}
android {
...
buildFeatures {
viewBinding = true
}
}
dependencies {
implementation("br.com.fortface:fortface:1.19.2:release@aar") {
isTransitive = true
}
}
Do not forget to synchronize your project with the Gradle files after making these changes.
3. Include Proguard rules
Our SDK already has obfuscation and minification for security assurance; however, some classes from the SDK need to be kept without obfuscation to ensure your app functions correctly. Add the following rules to your proguard-rules.pro file:
-keep class br.com.fortface.sdk.** { *; }
Permission
1. Adjust the AndroidManifest.xml
Our SDK uses the camera, so you must configure camera access permission in your app's manifest. To do so, add the following lines to the file:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
...
Our SDK also has a permission for location to collect geolocation coordinates of the device for reinforcement in antifraud mechanisms. If you want to collect the geolocation coordinates of the device, add the location permission to your app's manifest as well.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
...
2. Ensure Camera Access
For your application to request camera access permission, add the following code in your Activity:
Kotlin Snippet
- Kotlin
- Java
class YourActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
if (!allPermissionsGranted()) {
requestPermission()
}
}
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(this.baseContext, it) == PackageManager.PERMISSION_GRANTED
}
private fun requestPermission() {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
}
companion object {
const val REQUEST_CODE_PERMISSIONS = 10
val REQUIRED_PERMISSIONS = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_FINE_LOCATION, // Optional
Manifest.permission.ACCESS_COARSE_LOCATION // Optional
)
}
// ...
}
public class YourActivity extends AppCompatActivity {
private static final int REQUEST_CODE_PERMISSIONS = 10;
private static final String[] REQUIRED_PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}; // ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION are optional
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// ...
if (!allPermissionsGranted()) {
requestPermission();
}
}
private boolean allPermissionsGranted() {
for (String permission : REQUIRED_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);
}
// ...
}
After this configuration, your application is ready to access our SDK.
Pre-initialization
Before starting the capture process, it is necessary to establish the device integrity to ensure secure communication with the Fortface API. Therefore, you need to:
- Import our SDK into your app;
- Instantiate
FortfaceSdk.
Establish Device Integrity
Initialize the SDK and obtain the deviceRequestInfo.
- Kotlin
- Java
import br.com.fortface.sdk.FortfaceSdk
val deviceRequestInfo = FortfaceSdk.start(appContext, false)
println(deviceRequestInfo)
// Q4ezAXfMdAdW1s0xdwCcg0Jzj9kAjuNwzNrWMip4ADAylFQAGCgBOHT7HJYkPkXUPmLZ3XtJYOgTi/WKh+o2Vstk2MGy4qRz4fcBpCu+raS1ghHa4DDmqUjbSMPd3Fdo2zrcw0sb81FDf/Tos2A5UaIqMhzurkm0aYgC/izKhu3H+RQXJBHjFVKUIq8WPVbC/ITKon2T703C6fgdQtcpknaxAvIN2/eDRxBrsSuS3fbIi1TOoGAIi/Ezwj0utZLYUwhnKImaabvvXFdsvVxp6rHLiq1uHqZbm4tfRWJw4mkk47JHVEfUIJMFjS1ORpqoN1dmZzPQHAo0CtPfYGa9OB8NGnmgRRbWHXWrXPoptaRY31yoaT+HGwBwB/pfL8gUxoVppOYBUfIsvSQoaIQ+6g==
import br.com.fortface.sdk.FortfaceSdk;
String deviceRequestInfo = FortfaceSdk.start(appContext, false);
System.out.println(deviceRequestInfo);
In FortfaceSdk, the start method is used with 2 parameters and returns a String:
- Parameter
context: represents the context of your application. - Parameter
isDebugMode: a boolean that enables or disables debug mode. The default value isfalse- Use
trueto enable debug mode; - Use
falsein production, so that the device integrity is verified and, if not suitable for transactions, aFortfaceExceptionwith the message There is something wrong! will be thrown.
- Use
- Return stored in
deviceRequestInfo: a string used to validate the integrity of the device connected to our SDK. A newdeviceRequestInfois generated each time the method is called (the code above shows an example).
With deviceRequestInfo in hand, you can now perform a handshake call between your back-end and the Fortface API.
The
handshakeis an important security measure to establish reliable communication between your back-end and the Fortface API, allowing verification of device authenticity, sharing of sensitive information (encryption keys and sessions), and establishing a secure channel for data exchange.
Upon successful handshake, you are guaranteed that the device is secure and your app has the necessary information to proceed.
Capture and upload of documents
The maximum file size (PDF/Image) for upload is 4MB.
Larger files will be rejected with error code FileSizeTooBig.
Once device integrity is established, let’s see how to start the session and use the IFortfaceEngine interface to perform the capture.
Establishing the Device Session
Implement a class that extends IFortfaceEngine.
Document Capture
- Kotlin
- Java
import br.com.fortface.sdk.FortfaceManagerSession
import br.com.fortface.sdk.IFortfaceEngine
import br.com.fortface.sdk.utils.SessionDetails
class YourEngine(
appContext: Context,
sessionKey: String,
sessionId: String,
private val yourViewModel: ViewModel,
listDocumentTypes: List<DocumentTypeEnum>
) : IFortfaceEngine {
init {
val sessionDetails = SessionDetails(
getGeolocation = true // 👈 Optional: define if the SDK should request location permission and collect coordinates for antifraud reinforcement.
)
FortfaceManagerSession.startSessionDocumentEngine(
appContext,
this,
sessionId,
sessionKey,
listDocumentTypes,
null,
sessionDetails // can be omitted if you don't need the additional controls of usability to the session
)
}
}
import br.com.fortface.sdk.FortfaceManagerSession;
import br.com.fortface.sdk.IFortfaceEngine;
public class YourEngine implements IFortfaceEngine {
private final String sessionKey;
private final String sessionId;
private final ViewModel yourViewModel;
public YourEngine(Context appContext, String sessionKey, String sessionId, ViewModel yourViewModel, List<DocumentTypeEnum> listDocumentTypes, DocumentTypeEnum previousDocType) {
this.sessionKey = sessionKey;
this.sessionId = sessionId;
this.yourViewModel = yourViewModel;
// 👇 Optional: define if the SDK should request location permission and collect coordinates for antifraud reinforcement.
SessionDetails sessionDetails = new SessionDetails(true);
FortfaceManagerSession.startSessionDocumentEngine(
appContext,
this,
sessionId,
sessionKey,
listDocumentTypes,
previousDocType,
sessionDetails // can be omitted if you don't need the additional controls of usability to the session
);
}
}
In this class, you initialize FortfaceManagerSession and its method startSessionDocumentEngine, which has 5 parameters for document capture:
context: represents your application's context.engine: represents your Engine class that implements theIFortfaceEngineinterface of our SDK. This will be explained later in the Creating an Engine section.sessionId: session id generated by the Fortface API.sessionKey: encryption key generated by the Fortface API.sessionDetails: optional object that allows adding other controls of usability to the session.getGeolocation: define if the SDK should request location permission and collect coordinates for antifraud reinforcement.
The startSessionDocumentEngine method, which currently takes 7 parameters for document capture, will be discontinued. This method is already marked as obsolete (@Deprecated) and will stop functioning in future SDK versions.
It is recommended to update your implementation to use the new version of the method, which takes 5 parameters, without using the documentTypes and previousDocType parameters.
Document Upload
The maximum file size (PDF/Image) for upload is 4MB.
Larger files will be rejected with error code FileSizeTooBig.
- Kotlin
- Java
import br.com.fortface.sdk.FortfaceManagerSession
import br.com.fortface.sdk.IFortfaceEngine
class YourEngine(appContext: Context, sessionKey: String, sessionId: String, private val yourViewModel: ViewModel, listDocumentTypes:List<DocumentTypeEnum>
) : IFortfaceEngine {
init {
val sessionDetails = SessionDetails(
getGeolocation = true // 👈 Optional: define if the SDK should request location permission and collect coordinates for antifraud reinforcement.
)
FortfaceManagerSession.startUploadDocSessionEngine(appContext, this, sessionId, sessionKey, listDocumentTypes,true, null, sessionDetails)
}
}
import br.com.fortface.sdk.FortfaceManagerSession;
import br.com.fortface.sdk.IFortfaceEngine;
public class YourEngine implements IFortfaceEngine {
private final String sessionKey;
private final String sessionId;
private final ViewModel yourViewModel;
public YourEngine(Context appContext, String sessionKey, String sessionId, ViewModel yourViewModel, listDocumentTypes:List<DocumentTypeEnum>, previousDocType:DocumentTypeEnum) {
this.sessionKey = sessionKey;
this.sessionId = sessionId;
this.yourViewModel = yourViewModel;
// 👇 Optional: define if the SDK should request location permission and collect coordinates for antifraud reinforcement.
SessionDetails sessionDetails = new SessionDetails(true);
FortfaceManagerSession.startUploadDocSessionEngine(
appContext,
this,
sessionId,
sessionKey,
false,
sessionDetails // can be omitted if you don't need the additional controls of usability to the session
);
}
}
In this class, initialize FortfaceManagerSession and its method startUploadDocSessionEngine which has 6 parameters for document capture:
context: represents your application's context.engine: represents your Engine class that implements theIFortfaceEngineinterface of our SDK. This will be explained later in the Creating an Engine section.sessionId: session id generated by the Fortface API.sessionKey: encryption key generated by the Fortface API.openPhotoGalery: represents whether the SDK will open the photo gallery (true) or the file manager (false).sessionDetails: optional object that allows adding other controls of usability to the session.getGeolocation: define if the SDK should request location permission and collect coordinates for antifraud reinforcement.
The startUploadDocSessionEngine method, which currently takes 8 parameters for document capture, will be discontinued. This method is already marked as obsolete (@Deprecated) and will stop functioning in future SDK versions.
It is recommended to update your implementation to use the new version of the method, which takes 6 parameters, without using the documentTypes and previousDocType parameters.
By initializing the FortfaceManagerSession using the provided parameters, you correctly configure the secure communication session and ensure that the data transmitted between the app and the server is properly encrypted and protected.
Mock data for example:
AppContext:
Your application's context
Engine:
Reference to your Engine that implementsIFortfaceEngine
SessionId:
nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2k
SessionKey:
-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2k+o81Oiti4TDezZYD8Q\nzj2RjO5f/YQHGmC1v7CWC4AJpD9+FOXBBO1pImaSg1gb8kOobRFGWbVdiHm35+PF\nTJceH31r+jKnvfc1TshsQVGtYLm7x5E/GFcjpGx9LdSxiXC6cHdCJf3o02/lytBa\nu8NCoH9FpPjyKrdGdSRb2haviAuEV4N1UBd5uZIsacVqZj52i1z+I94gLVKBZ/UV\npaxjLPWWngmaxbyKE0sEbt9JGleiCb2P1kZA9sU4L4Po7WBNk0+QOsvW9QjvS1+6\ntcZwwIDll2LyUceiFgxF6GkuFcHlBZDDtzymDDC2IYrf9/FNBOPeV1JHXON8T6DY\nAwIDAQAB\n-----END PUBLIC KEY-----\n
The string that represents the sessionKey contains special characters (such as the line break \n) that must be preserved exactly as received from the Fortface API. Be careful with any accidental manipulation that may occur in:
- Form inputs
- Logs and monitoring systems
- String processing in your backend
- Transfers between services
- Database storage
Any change to these characters may cause the key validation to fail. Make sure the key is passed to the SDK exactly as received from the Fortface API.
For local frontend development only, you may reuse the same valid sessionKey as a mock as many times as necessary. The single-use restriction applies only in the context of backend development, when the Fortface API validates the key.
documentTypes: List of
DocumentTypeEnumwith the desired document options
previousDocType: Reference to the type of document captured previously (
DocumentTypeEnum) in case of capturing the second side of the same document.
Understanding the code snippet:
- The class constructor will call
FortfaceManagerSession.start - The session is created and the camera is rendered on the screen to capture the user's document.
ATTENTION!!
The flow is executed for each “side” of the document, i.e., front and back. Each must follow the complete flow, going through the Handshake and startSessionDocumentEngine. For capturing the second side, you must provide the document type (document side) recognized in the first capture; this information is available in the response from the Fortface API service. The property in the response JSON referring to the document type is the type property contained in the fortfaceSdk object.
Example response JSON from the Fortface service API for document capture:
{
"api":{
"timestamp":1741712439604,
"version":"v1.14"
},
"handshake":{
"sessionId":"187ffa8d-016d-c0962506f5ab",
"sessionKey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2t6V+LTwyClMN/2Dy5W8\nrJKMAwP45QTq+8e3RcNowUqKEDrsjSkBDYugYCaEuLY66pP3ndm8MfenHxuxAqGC\n3NagAUr83+kJufsizuUJTYC2/1CXeox8U1j4S0Ewt/4rr9SIZCwBisiFiT0THt6QFjE\nmwWMYVT4RjRUK8LV6pF1HJvjFHI6oXF2KjjFwVqXur5LB7sj9f70ddcp3Fiv/3Tn\nVQIDAQAB\n-----END PUBLIC KEY-----\n"
},
"message":"",
"providers":{
"fortfaceSdk":{
"automatic":true,
"confidence":0.73,
"type":"CNH_FRONT"
},
"identify":{
"status":"PENDING"
},
"ocr":{
"status":"PENDING",
"type":"ocr"
}
},
"sdk":{
"brand":"POCO",
"model":"M2012K11AG",
"platform":"android"
},
"title":""
}
Creating an Engine
Through the Engine, you can access the information processed by our SDK. To create an Engine, the class must implement the IFortfaceEngine interface; therefore, you must implement the finishedSessionEngine method. This method will receive the data processed by the SDK, which is a package containing an action and the captured image data.
Below is a complete implementation example of a capture, for instance, the YourEngine class that implements the IFortfaceEngine interface, containing the initialization of the startSessionEngine and/or startUploadDocSessionEngine session and handling of the SessionEngineResult callback.
Kotlin Snippet
- Kotlin
- Java
import br.com.fortface.sdk.Action
import br.com.fortface.sdk.SessionEngineResult
import br.com.fortface.sdk.FortfaceManagerSession
import br.com.fortface.sdk.IFortfaceEngine
class YourEngine(appContext: Context, sessionKey: String, sessionId: String, private val yourViewModel: ViewModel) : IFortfaceEngine {
init {
FortfaceManagerSession.startSessionDocumentEngine(appContext, this, sessionId, sessionKey)
}
override fun finishedSessionEngine(sessionEngineResult: SessionEngineResult) {
when (sessionEngineResult.action) {
Action.Capture -> yourViewModel.captured(sessionEngineResult) // Here the flow ends and these are the data to be sent
Action.Cancel -> yourViewModel.canceled() // Here the user canceled the capture and you should proceed with your cancellation flow
Action.Timeout -> yourViewModel.timeout() // Here the capture was canceled because time ran out. You should proceed with the timeout flow
Action.Error -> yourViewModel.error() // Here the capture was canceled because an error occurred. You should proceed with the error flow
else -> {}
}
}
}
import br.com.fortface.sdk.SessionEngineResult;
import br.com.fortface.sdk.FortfaceManagerSession;
import br.com.fortface.sdk.IFortfaceEngine;
public class YourEngine implements IFortfaceEngine {
private final Context appContext;
private final String sessionKey;
private final String sessionId;
private final ViewModel yourViewModel;
public YourEngine(Context appContext, String sessionKey, String sessionId, ViewModel yourViewModel) {
this.sessionKey = sessionKey;
this.sessionId = sessionId;
this.yourViewModel = yourViewModel;
FortfaceManagerSession.startSessionDocumentEngine(appContext, this, sessionId, sessionKey);
}
@Override
public void finishedSessionEngine(SessionEngineResult sessionEngineResult) {
switch (sessionEngineResult.getAction()) {
case Capture:
yourViewModel.captured(sessionEngineResult); // Here the flow ends and these are the data to be sent
break;
case Cancel:
yourViewModel.canceled(); // Here the user canceled the capture and you should proceed with your cancellation flow
break;
case Timeout:
yourViewModel.timeout(); // Here the capture was canceled because time ran out. You should proceed with the timeout flow
break;
case Error:
yourViewModel.error() // Here the capture was canceled because an error occurred. You should proceed with the error flow
break;
default:
break;
}
}
}
Note that the finishedSessionEngine method is a callback that receives a SessionEngineResult object. The callback has three pieces of information:
-
action: represents an enumerator containing:Capture: callback for a successful capture by the userCancel: callback for a capture canceled by the userTimeout: callback for a capture with the time limit reached by the user- This
actionrepresents the time during which the SDK remains open, whether a capture occurs or not. When time runs out, the SDK is terminated and the camera is closed; - The default time is 30 seconds;
- If you wish to change it, check the Customization section.
- This
Error: callback for a capture with an error during the process- This
actionrepresents an error generated during the capture and/or upload of the document
- This
-
getData: represents the captured data encrypted in a JSONObject. The JSON follows this structure:
{
key: String,
data: String,
imgData: String,
imgPreview: String
}
sessionDetails: is a type of data that contains anerrorCodeerrorCode: represents a code that can occur during the capture and/or upload process, the possible values are:DocumentNotFound: returned when the selected file (PDF/Image) cannot be found.FileSizeTooBig: returned when the selected file (PDF/Image) is larger than the allowed limit of4MB.FileCorrupted: returned when the selected file (PDF/Image) is corrupted.InvalidSessionKey: code returned when the sessionKey provided to the SDK is invalid.CameraAccessPermissionError: code returned when the user does not grant camera access to the application.ImageClosed: code returned when the capture process attempts to handle a frame whose image is unavailable.OutOfMemory: code returned when the device does not have enough available memory for the SDK to continue processing.
Thus, as shown in the example above, it is possible to assign each action to a specific implementation in your application. Additionally, once the information from the getData method is obtained, your application can transport it in the most convenient way to your backend and then to the Fortface API.
It is important to note that our SDK API will include enroll and identify flows, so feel free to architect Engines corresponding to each of these flows, a generic Engine, or any other desired solution.
Using Our SDK
In the SDK usage example, we will use the MVVM architecture. Thus, we have the view model:
- Kotlin
- Java
class YourViewModel: ViewModel() {
fun captured(sessionEngineResult: SessionEngineResult) {
// Implementation of what to do with the captured data
}
fun canceled() {
// Implementation for SDK cancellation
}
fun timeout() {
// Implementation for SDK timeout
}
fun error() {
// Implementation of error from the SDK
}
}
public class YourViewModel extends ViewModel {
public void captured(SessionEngineResult sessionEngineResult) {
// Implementation of what to do with the captured data
}
public void canceled(){
// Implementation for SDK cancellation
}
public void timeout() {
// Implementation for SDK timeout
}
public void error() {
// Implementation of error from the SDK
}
}
The SDK is free to be implemented in any project structure. In this documentation, we use the standard architecture pattern adopted in the market.
Below is an example code of the flow that should be implemented in your app to access our SDK:
- Kotlin
- Java
import br.com.fortface.sdk.FortfaceSdk
import androidx.activity.viewModels
//...
class YourActivity : AppCompatActivity() {
val yourViewModel: YourViewModel by viewModel()
//...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (!allPermissionsGranted()) {
requestPermission()
}
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
startEngine()
}
}
fun startEngine() {
val deviceRequestInfo = FortfaceSdk.start(this, false)
// Here you send it for the Fortface API handshake via your backend
// ...
// With the response you will have the sessionKey and sessionId
val sessionKey = "" // Response from the Fortface API
val sessionId = "" // Response from the Fortface API
YourEngine(this, sessionKey, sessionId, yourViewModel)
}
}
import br.com.fortface.sdk.FortfaceSdk;
import androidx.lifecycle.ViewModelProvider;
//...
public class YourActivity extends AppCompatActivity {
YourViewModel yourViewModel;
//...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
yourViewModel = new ViewModelProvider(this).get(YourViewModel.class);
if (!allPermissionsGranted()) {
requestPermission();
}
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startEngine();
}
});
// ...
}
private void startEngine() {
String deviceRequestInfo = FortfaceSdk.start(this, false);
// Here you send it for the Fortface API handshake via your backend
// ...
// With the response you will have the sessionKey and sessionId
String sessionKey = ""; // Response from the Fortface API
String sessionId = ""; // Response from the Fortface API
new YourEngine(this, sessionKey, sessionId, yourViewModel);
}
}
Versioning
To know which version of our SDK is being used, simply call the function FortfaceSDK.getVersion() which will return a String with its value. Example:
String sdkVersion = FortfaceSDK.getVersion()
System.out.println(sdkVersion);
// 1.17.0
Cancellation and Timeout Callback
When an attempt to capture the user's face is not successfully completed—for example, when the user cancels the capture or the capture does not occur within the specified time—it is important that this event is sent to the backend so that we have correct metrics for capture successes or failures.
To allow us to have data for canceled captures or those that timed out, our SDK includes callbacks for capture cancellation and capture timeout actions.
The SessionEngineResult received in the finishedSessionEngine function is an object that has two properties: data and action (the action performed by the SDK). Previously, the data field was only filled upon successful face capture.
As mentioned earlier in the Capture section, the data contains encrypted information and can be converted to JSON. However, unlike a successful capture, in this scenario after conversion to JSON, we will only have the following fields:
{
key: String,
data: String
}
Reminder: The keys “key” and “data” are generated by the SDK, sent to your backend, and then to the Fortface API.
Implementation Example
- The SDK detects that the capture was canceled.
- An encrypted object is created.
- The SDK is terminated and the generated payload along with the performed action is sent.
- In the implementation app, within the class that extends
IFortfaceEngine, the action is detected.
- Kotlin
import br.com.fortface.sdk.Action
import br.com.fortface.sdk.SessionEngineResult
import br.com.fortface.sdk.FortfaceManagerSession
import br.com.fortface.sdk.IFortfaceEngine
class YourEngine(appContext: Context, sessionKey: String, sessionId: String, private val yourViewModel: ViewModel) : IFortfaceEngine {
// ...
override fun finishedSessionEngine(sessionEngineResult: SessionEngineResult) {
when (sessionEngineResult.action) {
Action.Capture -> yourViewModel.captured(sessionEngineResult)
// When the cancel action is detected, the canceled function is called
// which receives the data generated by the SDK.
Action.Cancel -> yourViewModel.canceled(sessionEngineResult)
Action.Timeout -> yourViewModel.timeout(sessionEngineResult)
else -> {}
}
}
}
- Within your ViewModel, the
canceled()function is called.
- Kotlin
class YourViewModel: ViewModel() {
// ...
fun canceled(sessionEngineResult: SessionEngineResult) {
// Indicate that the cancel action was received
cancelAction.postValue(true)
// Create the cancellation payload in Metric format
createPayload(sessionEngineResult)
}
// ...
private fun createPayload(sessionEngineResult: SessionEngineResult) {
val encryptedPayload = sessionEngineResult.getData().toString()
if (encryptedPayload != "null") {
// Parse the JSON to the SDKData object (example below)
// In this case, the imgData field will be null
val sdkData = Gson().fromJson(encryptedPayload, SDKData::class.java)
// Indicate that a metric was received and send the Metrics
sessionEngineResultValue.postValue(Metrics(sdkData))
}
}
}
- Metrics Object
- Kotlin
@Keep
data class Metrics(
@SerializedName("sdkData")
var sdkData: SDKData
)
- SDKData Object
- Kotlin
@Keep
data class SDKData(
@SerializedName("key")
val key: String,
@SerializedName("data")
val data: String,
@SerializedName("imgData")
val imgData: String
)
- After triggering the metric reception, the Metrics are sent to the API.
- Kotlin
class YourFragment : Fragment() {
// ...
// Observer sees that a new metric is available and sends the data to the Metrics API
viewModel.sessionEngineResultValue.observe(viewLifecycleOwner) {
context?.let { context -> viewModel.sendMetricsToServer(context, it) }
}
}
Summary
- Verify camera access permission
- Capture the deviceRequestInfo
- Perform the Handshake with the Fortface API (via your backend)
- Start an Engine
- Receive the data in the Engine callback
- Send the data to the Fortface API (via your backend)
- Receive the response from the Fortface API and proceed with your business logic