Android v3.3.x UI Only
OVERVIEW
TrustVision SDK is the android SDK for TrustVision Engine. This document is for Clients who only use the UI of the SDK. It provides these features:
- Refactor code: merge full and uionly in a SDK version
- Separate the QR code scanning
- Scan QR while capturing front card
- Allow certain card types
- Cache SOD NFC
- Modify UI while reading NFC
- Face authentication
Specifications
- Gradle Version 7.3.3
- Tested with Gradle Plugin for Android Studio - version 7.2.2
- minSdkVersion 21
- targetSdkVersion 32
- Support Kotlin version 1.5.0 - 1.8.0
Integration Steps
1. Adding the SDK to your project
- Get library file
tv_sdk_client.zip, extract and put all files into a folder in android project. Example: folder${project.rootDir}/repo
Note : tv_sdk_client Each client will have a SDK name. That SDK name will contain the name of the client
app
root
repo
+--com
+--trustvision
+--tv_api_sdk
+--3.x.x
+--tv_api_sdk-3.x.x.aar
+--tv_api_sdk-3.x.x.pom
maven-metadata.xml
+--tv_core_sdk
+--tv_sdk_client
...
- Add the following set of lines to the Project (top-level)
build.gradle
buildscript {
ext.kotlin_version = '1.6.21' // or any version that >= 1.5 and < 1.8
repositories {
maven {
url 'https://maven.google.com'
}
mavenCentral()
google()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
maven { url "https://maven.google.com" }
maven { url "https://jitpack.io" }
maven { url "path/to/tvsdk/folder" } // example : maven { url "${project.rootDir}/repo" }
...
}
}
Note : If your project uses the new way to define repositories (central declaration of repositories), you must change repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) to repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
repositories {
google()
mavenCentral()
}
}
- Add the following set of lines to your
app/build.gradle
android {
...
aaptOptions {
noCompress "tflite"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation('com.trustvision:tv_sdk_client:3.x.x@aar') {
transitive = true
}
testImplementation 'junit:junit:4.12'
}
2. Initialize and config SDK
2.0. Initialize SDK
To initialize the SDK, add the following lines to your app, and it needs to be completed successfully before calling any other SDK functionalities.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TrustVisionSDK.INSTANCE.init(context, jsonConfigurationByServer, languageCode, new BaseTrustVisionSDK.TVInitializeListener() {
@Override
public void onInitSuccess() {
}
@Override
public void onInitError(@NonNull TVDetectionError error) {
}
});
}
Please note: The SDK requires Camera permissions to capture images. Camera permissions will be handled by the SDK if not already handled by the app.
where:
- jsonConfigurationByServer:
String. The jsonConfigurationByServer is optional but recommended. It's the setting specialized for each client from TS server. It's the response json string get by API https://ekyc.trustingsocial.com/api-reference/customer-api/#get-client-settings. When it's null or unmatched with the expected type then the default setting in the SDK will be used. - languageCode:
Stringthe code of the language that will show and sound to user. E.g Vietnamese (vi), English ( en).
2.1. Config
2.1.0 Language code
2.1.0.0 Get supported language codes list
TrustVisionSdk.INSTANCE.getSupportedLanguages();
2.1.1.1
Allow user to change the sdk language after initialization
TrustVisionSdk.INSTANCE.changeLanguageCode(String languageCode);
wherer:
- languageCode:
Stringthe code of the language that will show and sound to user. E.g Vietnamese (vi), English ( en).
2.2. Dynamic feature
2.2.0 Prerequisites
Need to have background of Dynamic Feature. Practice guideline reference
2.2.1 Configuration
Add placeholder placeholder_missing_resources.xml for missing resources, these values will be override from SDK:
<resources>
<string name="tv_title_activity_main" />
<integer name="google_play_services_version">1</integer>
<style name="tvAppTheme.NoActionBar" parent="AppTheme.NoActionBar" />
</resources>
Please execute this code before starting SDK if we're using Dynamic Feature in host app
TrustVisionSDK.INSTANCE.installDynamicFeature(it -> {
// We often execute this code to install some necessary resources for dynamic feature
SplitCompat.installActivity(it);
return Unit.INSTANCE;
});
3. Start the SDK
The SDK provides some built in Activities example activity to capture id, selfie, liveness...
3.0. Capture the ID
The id capturing activity will show the camera to capture image, preview the image. To start the id capturing activity.
3.0.1. Set config parameters
TVIDConfiguration.Builder builder=new TVIDConfiguration.Builder()
.setCardType(selectedCard)
.setCardSide(TVSDKConfiguration.TVCardSide.FRONT)
.setReadBothSide(false)
.setEnableSound(false)
.setEnablePhotoGalleryPicker(false)
.setEnableTiltChecking(false)
.setSkipConfirmScreen(false)
.setEnableScanNFC(true)
.setEnableScanQr(true);
TVIDConfiguration configuration=builder.build();
Options:
- setCardTypes:
List<TVCardType>. List of supported cards can be found byTrustVisionSDK.cardTypesafter you initialize the SDK with the jsonConfigurationByServer. If not, use :
Collections.singletonList(
new TVCardType(
"vn.national_id",
"CMND cũ / CMND mới / CCCD",
true,
TVCardType.TVCardOrientation.HORIZONTAL,
null,
null
)
);
- setCardSide:
TVCardSide. Card side to capture. - setReadBothSide
boolean. If true then the sdk will capture both side if possible; otherwise, then the card side defined in cardSide will be used. - setEnableSound:
boolean. Sound should be played or not. - setEnablePhotoGalleryPicker:
boolean. Allow user select id card image from phone gallery. - setEnableTiltChecking:
boolean. Check if the phone is parallel to the ground before taking the id card photo or not. - setSkipConfirmScreen:
boolean. Control whether the SDK should skip the confirmation screen. - setEnableScanNFC:
boolean. scan NFC chip of the id card or not. - setEnableScanQr:
boolean. scan QR code of the id card or not.
3.0.2. Start id capturing activity from configuration
TrustVisionSDK.INSTANCE.startIDCapturing(activity, configuration, new TVCapturingCallBack(){
@Override
public void onNewFrameBatch(FrameBatch frameBatch){
}
@Override
public void onError(TVDetectionError error){
}
@Override
public void onSuccess(TVDetectionResult result){
}
@Override
public void onCanceled(){
}
@Override
public String readIdCardNumber(@NonNull TVImageClass image) {
}
});
where:
- activity: is the current Activity being displayed
- configuration: the configuration would like to pass to id capturing activity
- callback: is an object of type
TVCapturingCallBack. It is an interface that has 3 methods- onNewFrameBatch:
NewFrameBatchCallback. can be called multiple times during the capturing to return frame data.- frameBatch:
FrameBatch- getId():
String. batch id generated by TV SDK - getFrames():
List<TVFrameClass>. batch frame to push - getMetadata():
Map<String, String>. batch metadata to push - getValidVideoIds()
Set<String>. For debugging purpose only
- getId():
- frameBatch:
- onSuccess method that will be called in case of success. The
onSuccessmethod has one parameter.- result :
TVDetectionResult. has the following methods:- getFrontCardImage():
TVImageClass - getBackCardImage():
TVImageClass - getFrontIdQr():
TVCardQr - getBackIdQr():
TVCardQr - getNfcInfoResult()
- getFrontCardImage():
- result :
- onError:
ErrorCallback. Will be called when an error has occurred during the capturing.- error:
TVDetectionError
- error:
- onCanceled:
CancellationCallback. Will be called when the journey has been cancelled (e.g user clicked on back button...) - readIdCardNumber: method that will be called in case of scan NFC to read SDK Id number from the image. The readIdCardNumber method has a parameter and return a string which is the id number of the card.
- image:
TVImageClass. image of back id card
- image:
- onNewFrameBatch:
3.0.3. Handle onNewFrameBatch callback
With each batch that returned by onNewFrameBatch(FrameBatch) callback,
call the below api to upload the data to server, and store the frame batch id that responses from the API, keep it
corresponding with frameBatch.getId() - local id
https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
For example:
// this dictionary will be used for ID Tampering Verification
Map frontCardFrameBatchIdsDictionary = new HashMap<String, String>();
Map backCardFrameBatchIdsDictionary = new HashMap<String, String>();
// frameBatchIdsDictionary.put(
// key = <id_returned_from_sdk>,
// value = <id_responded_from_server>
// );
@Override
public void onNewFrameBatch(FrameBatch frameBatch) {
Gson gson = new Gson();
String framesStr = gson.toJson(frameBatch.getFrames());
Map<String, Object> params = new HashMap<>();
params.put("frames", framesStr);
params.put("metadata", frameBatch.getMetadata());
params.put("label", "video");
String jsonToBeUploaded=gson.toJson(map);
// upload frame batch to server using this api:
// https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
YourResponseObject uploadingResult = yourMethodToUploadFrameBatch(jsonToBeUploaded);
// Keep the id that generated by the SDK corresponding with the one responded from server
if (cardSide == TVSDKConfiguration.TVCardSide.FRONT) {
frontCardFrameBatchIdsDictionary.put(
key = frameBatch.batchId,
value = uploadingResult.fileId
);
} else {
backCardFrameBatchIdsDictionary.put(
key = frameBatch.batchId,
value = uploadingResult.fileId
);
}
}
3.0.4. Handle ID capturing results
3.0.4.1 Remove redundant frame batch ids
// These lists contain all valid frame batch ids that responded by server
var validFrontCardServerFrameBatchIds: List<String>? = null
var validBackCardServerFrameBatchIds: List<String>? = null
override fun onSuccess(result: TVDetectionResult) {
// the batch id list is null when Frame Recording feature is disabled by client settings.
// Wait until every Frame batch has been uploaded to server before calling this
if (everyFrameBatchUploadingCompleted) {
result.frontCardFrameBatchIds?.also {
validFrontCardServerFrameBatchIds = removeRedundantFrameBatchIds(
frontCardFrameBatchIdsDictionary,
it
)
}
result.backCardFrameBatchIds?.also {
validBackCardServerFrameBatchIds = removeRedundantFrameBatchIds(
backCardFrameBatchIdsDictionary,
it
)
}
}
}
private fun removeRedundantFrameBatchIds(
batchIdsDictionary: MutableMap<String, String>,
validIdsFromSDK: Collection<String>
): List<String> {
val iter: MutableIterator<Map.Entry<String, String>> = batchIdsDictionary.entries.iterator()
while (iter.hasNext()) {
val (key1) = iter.next()
if (!validIdsFromSDK.contains(key1)) {
iter.remove()
}
}
return batchIdsDictionary.values.toList()
}
3.0.4.2. Get Image Ids to be used in a particular use case
Use this API https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image The images should be uploaded as JPEG data with 100% quality. For example:
{
"file": "<byte[] dataToUpload>",
"label": "proper label, check the API document for detail"
}
3.0.4.3. Check ID Tampering
Call this API https://ekyc.trustingsocial.com/api-reference/customer-api/#request-detect-id-card-tampering with params:
{
"image": {
"id": "<frontCardId>"
},
"image2": {
"id": "<backCardId>"
},
"qr1_images": [
{
"id": "<qrId>"
}
],
"card_type": "<result.cardType.getCardId()>",
"videos": [
{
"id": "<validFrontCardServerFrameBatchIds.get(index)>"
},
{
"id": "<validFrontCardServerFrameBatchIds.get(index + 1)>"
},
...
{
"id": "<validBackCardServerFrameBatchIds.get(index)>"
},
{
"id": "<validBackCardServerFrameBatchIds.get(index + 1)>"
},
...
]
}
3.0.4.4 Upload QR images
if result.getFrontIdQr().isRequired() is true then result.getFrontIdQr().getImages() array should be non-empty. Otherwise, clients should be warned to re-capture id card photos.
QR images will be uploaded with this api: https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image
TVImageClass frontQrImage = result.getFrontIdQr().getImages().get(i);
Map<String, String> metadata = frontQrImage.getMetadata();
String label = frontQrImage.getLabel();
byte[] data = frontQrImage.getImageByteArray();
*The same logic will be applied to result.getBackIdQr()
3.0.5 Scan NFC in back ID card capturing step
After capture the back card, if the card has nfc chip, SDK will call readIdCardNumber method in background thread. With image that returned by readIdCardNumber,
call api to detect id number of the card then return id number to start flow scan NFC. If id number is null or empty, SDK skip flow scan NFC and continue
override fun readIdCardNumber(image: TVImageClass): String? {
var idNumber: String? = null;
// call api or do any thing to read and return id number
// TODO
return idNumber;
}
3.1. Capture the selfie
The selfie capturing activity will show the camera to capture image, preview the image, verify liveness. To start the selfie capturing activity.
3.1.1. Set config parameters
TVSelfieConfiguration.Builder builder = new TVSelfieConfiguration.Builder()
.setCameraOption(TVSDKConfiguration.TVCameraOption.FRONT)
.setEnableSound(false)
.setLivenessMode(TVLivenessMode.PASSIVE)
.setSkipConfirmScreen(false);
TVSelfieConfiguration configuration = builder.build();
Options:
- setCameraOption:
TVCameraOption. Camera mode - setEnableSound:
boolean. Sound should be played or not - setLivenessMode:
TVLivenessMode. Liveness verification mode - setSkipConfirmScreen:
boolean. Control whether the SDK should skip the confirmation screen.
3.1.2. Start selfie capturing activity from configuration
TrustVisionSDK.INSTANCE.startSelfieCapturing(activity, configuration, new TVCapturingCallBack() {
@Override
public void onNewFrameBatch(FrameBatch frameBatch) {
}
@Override
public void onError(TVDetectionError error) {
}
@Override
public void onSuccess(TVDetectionResult result) {
}
@Override
public void onCanceled(){
}
});
where:
- activity: is the current Activity being displayed
- configuration: the configuration would like to pass to selfie capturing activity
- callback: is an object of type
TVCapturingCallBack. It is an interface that has 3 methods- onNewFrameBatch:
NewFrameBatchCallback. can be called multiple times during the capturing to return frame data.- frameBatch:
FrameBatch - getId():
String. batch id generated by TV SDK - getFrames():
List<TVFrameClass>. batch frame to push - getMetadata():
Map<String, String>. batch metadata to push - getValidVideoIds()
Set<String>. For debugging purpose only
- frameBatch:
- onSuccess method that will be called in case of success. The
onSuccessmethod has one parameter.- result :
TVDetectionResult. has the following methods:- getSelfieImages():
List<SelfieImage> - getLivenessFrameBatchIds():
Collection<String> - getLivenessMetadata():
JSONObject
- getSelfieImages():
- result :
- onError:
ErrorCallback. Will be called when an error has occurred during the capturing.- error:
TVDetectionError
- error:
- onCanceled:
CancellationCallback. Will be called when the journey has been cancelled (e.g user clicked on back button...)
- onNewFrameBatch:
3.1.3. Handle onNewFrameBatch callback
With each batch that returned by onNewFrameBatch(FrameBatch) callback,
call the below api to upload the data to server, and store the frame batch id that responses from the API, keep it
corresponding with frameBatch.getId() - local id
https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
For example:
// this dictionary will be used for Liveness verification
Map selfieFrameBatchIdsDictionary = new HashMap<String, String>();
// frameBatchIdsDictionary.put(
// key = <id_returned_from_sdk>,
// value = <id_responded_from_server>
// );
@Override
public void onNewFrameBatch(FrameBatch frameBatch) {
Gson gson = new Gson();
String framesStr = gson.toJson(frameBatch.getFrames());
Map<String, Object> params = new HashMap<>();
params.put("frames", framesStr);
params.put("metadata", frameBatch.getMetadata());
params.put("label", "video");
String jsonToBeUploaded = gson.toJson(map);
// upload frame batch to server using this api:
// https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
YourResponseObject uploadingResult = yourMethodToUploadFrameBatch(jsonToBeUploaded);
// Keep the id that generated by the SDK corresponding with the one responded from server
frameBatchIdsDictionary.put(
key = frameBatch.getId(),
value = uploadingResult.fileId
);
}
3.1.4. Handle selfie results
3.1.4.1 Remove redundant frame batch ids
// These lists contain all valid frame batch ids that responded by server
var validServerFrameBatchIds: List<String>? = null
override fun onSuccess(result: TVDetectionResult) {
// the batch id list is null when Frame Recording feature is disabled by client settings.
// Wait until every Frame batch has been uploaded to server before calling this
if (everyFrameBatchUploadingCompleted) {
result.livenessFrameBatchIds?.also {
validServerFrameBatchIds = removeRedundantFrameBatchIds(
selfieFrameBatchIdsDictionary,
it
)
}
}
}
private fun removeRedundantFrameBatchIds(
batchIdsDictionary: MutableMap<String, String>,
validIdsFromSDK: Collection<String>
): List<String> {
val iter: MutableIterator<Map.Entry<String, String>> = batchIdsDictionary.entries.iterator()
while (iter.hasNext()) {
val (key1) = iter.next()
if (!validIdsFromSDK.contains(key1)) {
iter.remove()
}
}
return batchIdsDictionary.values.toList()
}
3.1.4.2. Get Image Ids
Use this api https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image
to get image ids with the inputs are the elements of result.getSelfieImages()
The images should be uploaded as JPEG data with 100% quality.
For example:
// These lists of image ids will be used in Liveness Verification
List<String> frontalImageIds = new ArrayList<>();
List<String> gestureImageIds = new ArrayList<>();
@Override
public void onSuccess(TVDetectionResult result) {
handleSelfieImages(result.getSelfieImages());
}
private void handleSelfieImages(List<SelfieImage> selfieImages) {
for (selfieImage: selfieImages) {
// Handle frontal images
if (selfieImage.getFrontalImage() != null && selfieImage.getFrontalImage().getImageByteArray() != null){
byte[] frontalImageByteArray = selfieImage.getFrontalImage().getImageByteArray();
// frontalImageId is the id of the image, returned from server when the uploading API is completed successfully
String frontalImageId = yourUploadImageMethod(frontalImageByteArray);
frontalImageIds.add(frontalImageId);
}
// Handle gesture images
if (selfieImage.getGestureImage() != null && selfieImage.getGestureImage().getImageByteArray() != null){
byte[] gestureImageByteArray = selfieImage.getGestureImage().getImageByteArray();
// gestureImageId is the id of the image, returned from server when the uploading API is completed successfully
String gestureImageId = yourUploadImageMethod(gestureImageByteArray);
gestureImageIds.add(gestureImageId);
}
}
}
Upload Image API request, parameters:
{
"file": "<byte[] dataToUpload>",
"label": "<proper label, check the API document for detail>"
}
3.1.4.3. Liveness Verification
API document: https://ekyc.trustingsocial.com/api-reference/customer-api/#verify-face-liveness
Call the above api with below parameters:
imagesfield
{
"images": [
{
"id": "<frontalImageIds.get(index)>"
},
{
"id": "<frontalImageIds.get(index + 1)>"
},
...
]
}
gesture_imagesfield
{
"gesture_images": [
{
"gesture": "<result.getSelfieImages().get(index).getGestureType().toGestureType().toLowerCase()>",
"images": [
{
"id": "<gestureImageIds.get(index)>"
}
]
},
{
"gesture": "<result.getSelfieImages().get(index + 1).getGestureType().toGestureType().toLowerCase()>",
"images": [
{
"id": "<gestureImageIds.get(index + 1)>"
}
]
},
...
]
}
videosfield
{
"videos": [
{
"id": "<validServerFrameBatchIds.get(index)>"
},
{
"id": "<validServerFrameBatchIds.get(index + 1)>"
},
...
]
}
metadatafield
{
"metadata": "<result.getLivenessMetadata()>"
}
3.2. Scan QR
The QR scanner activity will show the camera to scan image, preview the image. To start the QR scanner activity.
3.2.1. Set config parameters
TVQRConfiguration.Builder builder= new TVQRConfiguration.Builder()
.setCardType(selectedCard)
.setCardSide(TVSDKConfiguration.TVCardSide.FRONT)
.setEnableSound(false)
.setSkipConfirmScreen(false);
TVQRConfiguration configuration=builder.build();
Options:
- setCardType:
TVCardType. List of supported cards can be found byTrustVisionSDK.getCardTypes()if you set jsonConfigurationByServer when init SDK. If not, use :
new TVCardType(
"vn.national_id",
"CMND cũ / CMND mới / CCCD",
true,
TVCardType.TVCardOrientation.HORIZONTAL,
null,
null
);
- setCardSide:
TVCardSide. Card side to capture. - setEnableSound:
boolean. Sound should be played or not. - setSkipConfirmScreen:
boolean. Control whether the SDK should skip the confirmation screen.
3.2.2. Start QR Scanning activity from configuration
TrustVisionSDK.INSTANCE.startQRScanning(activity, configuration, new TVCapturingCallBack(){
@Override
public void onError(TVDetectionError error){
}
@Override
public void onSuccess(TVDetectionResult result){
}
@Override
public void onCanceled(){
}
});
where:
- activity: is the current Activity being displayed
- configuration: the configuration would like to pass to QR scanning activity
- callback: is an object of type
TVCapturingCallBack. It is an interface that has 3 methods- onSuccess method that will be called in case of success. The
onSuccessmethod has one parameter.- result :
TVDetectionResult. has the following methods:- getFrontIdQr():
TVCardQr - getBackIdQr():
TVCardQr
- getFrontIdQr():
- result :
- onError:
ErrorCallback. Will be called when an error has occurred during the capturing.- error:
TVDetectionError
- error:
- onCanceled:
CancellationCallback. Will be called when the journey has been cancelled (e.g user clicked on back button...)
- onSuccess method that will be called in case of success. The
3.2.3 Upload QR images
if result.getFrontIdQr().isRequired() is true then result.getFrontIdQr().getImages() array should be non-empty. Otherwise, clients should be warned to re-capture id card photos.
QR images will be uploaded with this api: https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image
TVImageClass frontQrImage = result.getFrontIdQr().getImages().get(i);
Map<String, String> metadata = frontQrImage.getMetadata();
String label = frontQrImage.getLabel();
byte[] data = frontQrImage.getImageByteArray();
*The same logic will be applied to result.getBackIdQr()
3.3. Scan NFC
The NFC scanner activity will show the guideline screen, the scanner popup. To start the NFC scanner activity.
3.3.1. Set config parameters
TVNfcConfiguration.Builder builder = new TVNfcConfiguration.Builder()
.setNfcCode(nfcCode)
.setSOD(sod)
.setRequestReadImageNfc(true)
.setRequestIntegrityCheckNfc(true)
.setRequestCloneDetectionNfc(true)
.setNfcMaxRetries(5);
TVNfcConfiguration configuration = builder.build();
Options:
- setNfcCode:
Stringis the id number of ID card - setSOD:
String(optional) is the sod of ID card (MM/DD/YYYY) - setRequestReadImageNfc:
booleanread image in the chip when scan nfc or not - setRequestIntegrityCheckNfc:
booleancheck integrity of the chip when scanning nfc or not - setRequestCloneDetectionNfc:
booleancheck clone of the chip when scanning nfc or not - setNfcMaxRetries:
Int. The maximum number of times the SDK retries an NFC scanning before giving up
3.0.2. Start nfc scanning activity from configuration
TrustVisionSDK.INSTANCE.startNfcScanning(activity, configuration, new TVCapturingCallBack() {
@Override
public void onCanceled() {
}
@Override
public void onSuccess(@NonNull TVDetectionResult result) {
}
@Override
public void onError(@NonNull TVDetectionError error) {
}
});
where:
- activity: is the current Activity being displayed
- configuration: the configuration would like to pass to nfc scanning activity
- callback: is an object of type
TVCapturingCallBack. It is an interface that has 3 methods- onSuccess method that will be called in case of success. The
onSuccessmethod has one parameter.- result :
TVDetectionResult. has the following methods:- getNfcInfoResult():
TVNfcInfoResult
- getNfcInfoResult():
- result :
- onError:
ErrorCallback. Will be called when an error has occurred during the capturing.- error:
TVDetectionError
- error:
- onCanceled:
CancellationCallback. Will be called when the journey has been cancelled (e.g user clicked on back button...)
- onSuccess method that will be called in case of success. The
3.4. Error handling:
// [FlowStartingFunc]: startIdCapturing, startSelfieCapturing, startQRScanning, startNfcScanning
TrustVisionSDK.INSTANCE.[FlowStartingFunc](..., builder.build(), new TVCapturingCallBack() {
@Override
public void onError(TVDetectionError error) {
String message = error.getErrorDescription();
Log.d("", message);
showToast(message);
///////////////////////////////////////
// ERROR HANDLER
int code = error.getErrorCode();
String description = error.getErrorDescription();
switch code {
case TVDetectionError.CONFIGURATION_ERROR:
// Invalid configuration
case TVDetectionError.DETECTION_ERROR_PERMISSION_MISSING:
// No camera permission.
case TVDetectionError.DETECTION_ERROR_CAMERA_ERROR:
// The camera can't be opened.
case TVDetectionError.DETECTION_ERROR_SDK_INTERNAL:
// The SDK has an unexpected error.
case TVDetectionError.DETECTION_ERROR_NFC:
// The SDK has an unexpected error when scanning NFC
}
}
@Override
public void onSuccess(TVDetectionResult result) {
}
@Override
public void onCanceled() {
}
});
4. Additional built-in API
The SDK provides some built-in API for quick detection
4.0. Detect if device support NFC
Allow users to quick check if device support NFC so that they can determine for their next step
TrustVisionSDK.INSTANCE.isNfcSupport(Context): Boolean
API Interface
1. TVLivenessResult
| Method | Type | description |
|---|---|---|
isLive | Boolean | Determines whether the selfie is live or not |
getScore() | float | The score from 0 to 1 |
2. TVDetectionResult
| Method | Type | description |
|---|---|---|
getSelfieImages() | List<SelfieImage> | List of images that each item contains the bitmap of the selfie image |
getSelfieFrameBatchIds() | Final list of Selfie's local frame batch IDs. Local batch ids that not in this list are invalid and their corresponding server IDs shouldn't be used | |
getLivenessMetadata() | JSONObject | Collected data during liveness checking process |
| Method | Type | description |
|---|---|---|
getFrontCardImage() | TVImageClass | Contains bitmap of the front image |
getBackCardImage() | TVImageClass | Contains bitmap of the back image |
getQRImage() | TVImageClass | Contains bitmap of the QR image |
getFrontCardFrameBatchIds() | Set<String> | Final list of front side's local frame batch IDs. Local batch ids that not in this list are invalid and their corresponding server IDs shouldn't be used |
getBackCardFrameBatchIds() | Set<String> | Final list of back side's local frame batch IDs. Local batch ids that not in this list are invalid and their corresponding server IDs shouldn't be used |
getNfcInfoResult() | TVNfcInfoResult | Contains info from nfc chip. Use it to call api verify NFC |
| Method | Type | description |
|---|---|---|
getError() | TVDetectionError | The error found when doing any detection |
3. SelfieImage
| Method | Type | description |
|---|---|---|
getGestureType() | FaceDetectionType | Gesture type of the selfie image |
getFrontalImage() | TVImageClass | Frontal image of the selfie image |
getGestureImage() | TVImageClass | Gesture image of the selfie image |
4. FaceDetectionType
| Method | Type | description |
|---|---|---|
getType() | int | Represent a gesture type |
int NEUTRAL = 1
int TURN_LEFT = 5
int TURN_RIGHT = 6
int FACE_UP = 7
int FACE_DOWN = 8
5. TVImageClass
| Method | Type | description |
|---|---|---|
getLabel() | String | Label of the Image class. |
getImage() | Bitmap | Captured Bitmap |
6. TVDetectionError
| Method | Type | description |
|---|---|---|
getErrorCode() | int | Error code |
getErrorDescription() | String | Error description |
Error code is one of the below list
int TVDetectionError.DETECTION_ERROR_PERMISSION_MISSING = 1004
int TVDetectionError.DETECTION_ERROR_CAMERA_ERROR = 1005
int TVDetectionError.DETECTION_ERROR_SDK_INTERNAL = 1007
7. TVCameraOption (Enum)
- TVCameraOption.FRONT: Use front camera
- TVCameraOption.BACK: Use back camera
- TVCameraOption.BOTH: The screen will have a button to switch between front & back camera
8. TVLivenessMode (Enum)
- TVLivenessMode.NONE: no liveness verification. Just capture the selfie.
- TVLivenessMode.PASSIVE: Use texture-based approach.
- TVLivenessMode.ACTIVE: Use challenge-response approach. User needs to follow and finish all steps when capturing selfie such as turn left, right, up, smile, open mouth...
9. TVDefaultCameraSide (Enum)
- TVDefaultCameraSide.FRONT
- TVDefaultCameraSide.BACK
10. FrameBatch
| Method | Type | description |
|---|---|---|
getFrames() | List<TVFrameClass> | Recorded frames during the capturing |
getId() | String | Local ID of the batch, to be corresponds with the ID responded from server after the frame batch is pushed |
getMetadata() | Map<String, String> | Metadata of the batch |
getValidVideoIds() | Set <String> | For debugging purpose only |
11. TVFrameClass
| Method | Type | description |
|---|---|---|
getFramesBase64() | String | The data of the frame as a base64 String |
getIndex() | String | Index of this frame in the list of recorded frames |
getLabel() | String | Label of this frame |
11. ErrorCallback (Callback)
Will be called in case failed. Parameters:
- error:
TVDetectionError.
12. CancellationCallback (Callback)
Will be called in case the sdk is cancelled. No parameters.
13. TVNfcInfoResult
| Method | Type | Description |
|---|---|---|
getCom() | String | |
getSod() | String | |
getDg1() | String | |
getDg2() | String | |
getDg13() | String | |
getDg14() | String | |
getDg15() | String | |
getCloneStatus() | TVNfcVerificationStatus |
14. TVNfcVerificationStatus
| Method | Type | Description |
|---|---|---|
getError() | TVDetectionError | |
getVerdict() | TVNfcVerdict | TVNfcVerdict.NOT_CHECKED TVNfcVerdict.ALERT TVNfcVerdict.GOOD TVNfcVerdict.ERROR |
UI Customization
This document introduces how to enable the ability to customize UI components of TrustingVision SDK.
Default UI prototypes
Check out the default UI of TrustingVision SDK. We provide you the ability to change and modify many UI components: background colors, font interfaces, font sizes, icons, buttons.





Before initialize the SDK
Initialize and change properties of TVTheme class. If any of which is not set, it will get default value.
After that, input the instance of TVTheme as a parameter of the TV SDK's initialization method. See Initialize TV SDK
TVTheme let you custom and override attributes, which includes:
| Properties/Functions | Type | Description |
|---|---|---|
idCapturingTheme | TVIdCapturingTheme | Attributes that change the UI of ID Card Detection screen. |
idConfirmationTheme | TVIdConfirmationTheme | Attributes that change the UI of ID Confirmation screen. |
selfieCapturingTheme | TVSelfieCapturingTheme | Attributes that change the UI of Selfie Capturing screen. |
selfieConfirmationTheme | TVSelfieConfirmationTheme | Attributes that change the UI of Selfie Confirmation screen. |
qrGuidelinePopupTheme | TVQrPopupTheme | Modifying UI of QR guideline popup. |
qrRetryPopupTheme | TVQrPopupTheme | Modifying UI of QR retry popup. |
clone() | () -> TVTheme | A function that returns a deep copy of TVTheme's instance itself. |
Common UI components
Object TVThemeDefaultValues helps you to quickly change some common UI components that will be used across the whole SDK.
In case a specific Screen's theme is set, it will override TVThemeDefaultValues's properties.
| Properties | Type | Description |
|---|---|---|
normalLabelTheme | TVLabelTheme | Normal text of SDK. |
titleLabelTheme | TVLabelTheme | The title of every screen (located on the top-most, centered of screen). |
errorLabelTheme | TVLabelTheme | This text is shown as if any user misconduction or system failure occurred during the detection process. |
instructionLabelTheme | TVLabelTheme | Instruction text. |
timeoutLabelTheme | TVLabelTheme | The count down text. |
The object TVLabelTheme can be described in this table below:
| Properties/Functions | Type | Label's |
|---|---|---|
font | Typeface | font family and style |
textSize | Float | text size |
textColor | @ColorInt Int | text color |
textGravity | Int | text alignment of its frame. E.g Gravity.Center, Gravity.Start... |
backgroundColors | [@ColorInt Int] | background colors. If total elements of this array is >= 2, the background color is gradient, else it'd be solid. |
isBackgroundGradientHorizontal | Boolean | background gradient direction |
cornerRadius | Float | rounded corner |
isHidden | Boolean | hide the label |
borderWidth | Float | border width |
borderColor | @ColorInt Int | border color |
clone() | () -> TVLabelTheme | A function that returns a deep copy of TVLabelTheme's instance itself. |
Here is a snipped code example:
private void customizeTVCommonThemes() {
// Common Title label theme
TVLabelTheme titleLabelThemeDefault = TVThemeDefaultValues.getTitleLabelTheme();
titleLabelThemeDefault.setFont(your_font);
// there are more to be customized...
// Common Normal label theme
TVLabelTheme normalLabelThemeDefault = TVThemeDefaultValues.getNormalLabelTheme();
normalLabelThemeDefault.setTextSize(your_text_size);
// there are more to be customized...
// Common Instruction label theme
TVLabelTheme instructionLabelTheme = TVThemeDefaultValues.getInstructionLabelTheme();
instructionLabelTheme.setTextColor(your_text_color);
// there are more to be customized...
// Common Error label theme
TVLabelTheme errorLabelThemeDefault = TVThemeDefaultValues.getErrorLabelTheme();
errorLabelThemeDefault.setCornerRadius(your_corner_radius);
// there are more to be customized...
// Common Timeout label theme
TVLabelTheme timeoutLabelThemeDefault = TVThemeDefaultValues.getTimeoutLabelTheme();
timeoutLabelThemeDefault.setBackgroundColors(your_background_colors);
// there are more to be customized...
}
ID Card Detection: UI customization

Class TVIdCapturingTheme
If a property is not set then the default value will be used.
| Properties/Functions | Type | Description |
|---|---|---|
titleLabelTheme | TVLabelTheme | See Common UI components section. |
instructionLabelTheme | TVLabelTheme | |
errorLabelTheme | TVLabelTheme | |
timeoutLabelTheme | TVLabelTheme | |
normalLabelTheme | TVLabelTheme | |
qrInstructionLabelTheme | TVLabelTheme | The instruction text that show during QR scanning process. |
closeButtonLocation | enumTVButtonLocation | The position of close button to device orientation: .TOP_LEFT: to the left of the title .TOP_RIGHT: to the right of the title .NONE: hide the button |
showTrademark | Boolean | Show the trademark text or not. |
backgroundColor | @ColorInt Int | Background color of the screen. Default value is black with 60% opacity. |
captureButtonImage | Bitmap | The image of the capture button. |
captureButtonDisableImage | Bitmap | The image of the disabled capture button. |
closeButtonImage | Bitmap | The image of the close view button. |
maskViewNeutralImage | Bitmap | The mask image of camera view when start the ID Capture flow. |
maskViewSuccessImage | Bitmap | The mask image of camera view when detected a valid ID card. |
maskViewErrorImage | Bitmap | The mask image of camera view when cannot detect any ID card. |
qrInstructionBackgroundImage | Bitmap | The image behind the QR instruction text. |
qrMaskViewNeutralImage | Bitmap | The mask image of camera view when start QR detection or not detected any QR code. |
qrMaskViewSuccessImage | Bitmap | The mask image of camera view when detected a valid QR code. |
qrMaskViewErrorImage | Bitmap | The mask image of camera view when detected an invalid QR code. |
loadingImage | Bitmap | Loading indicator in image. |
clone() | () -> TVIdCapturingTheme | A function that returns a deep copy of TVIdCapturingTheme's instance itself. |
ID Card Confirmation: UI customization

Class TVIdConfirmationTheme
If a property is not set then the default value will be used.
| Properties/Functions | Type | Description |
|---|---|---|
titleLabelTheme | TVLabelTheme | See Common UI components section. |
errorLabelTheme | TVLabelTheme | |
normalLabelTheme | TVLabelTheme | |
closeButtonLocation | enumTVButtonLocation | The position of close button to device orientation: .TOP_LEFT: to the left of the title .TOP_RIGHT: to the right of the title .NONE: hide the button |
showTrademark | Boolean | Show the trademark text or not. |
backgroundColor | @ColorInt Int | Background color of the screen. Default value is black with 60% opacity. |
closeButtonImage | Bitmap | The image of the close view button. |
confirmButtonImage | Bitmap | The image of the "Look good" button. |
retryButtonImage | Bitmap | The image of the "Try again" button. |
icQrResultSuccessImage | Bitmap | Icon before text that scanned QR successfully. |
icQrResultErrorImage | Bitmap | Icon before text that scanned QR failed. |
maskViewImage | Bitmap | The mask image of camera view showing captured image. |
loadingImage | Bitmap | Loading indicator in image. |
clone() | () -> TVIdConfirmationTheme | A function that returns a deep copy of TVIdConfirmationTheme's instance itself. |
Selfie Capturing: UI customization

Class TVSelfieCapturingTheme
If a property is not set then the default value will be used.
| Properties/Functions | Type | Description |
|---|---|---|
titleLabelTheme | TVLabelTheme | See Common UI components section. |
instructionLabelTheme | TVLabelTheme | |
errorLabelTheme | TVLabelTheme | |
timeoutLabelTheme | TVLabelTheme | |
normalLabelTheme | TVLabelTheme | |
closeButtonLocation | enumTVButtonLocation | The position of close button to device orientation: .TOP_LEFT: to the left of the title .TOP_RIGHT: to the right of the title .NONE: hide the button |
showTrademark | Boolean | Show the trademark text or not. |
backgroundColor | @ColorInt Int | Background color of the screen. Default value is black with 60% opacity. |
captureButtonImage | Bitmap | The image of the capture button. |
captureButtonDisableImage | Bitmap | The image of the disabled capture button. |
closeButtonImage | Bitmap | The image of the close view button. |
switchCameraSideImage | Bitmap | The image of switch camera button. |
maskViewNeutralImage | Bitmap | The mask image of camera view when start the selfie flow. |
maskViewSuccessImage | Bitmap | The mask image of camera view when detected a valid face. |
maskViewErrorImage | Bitmap | The mask image of camera view when cannot detect any valid face. |
progressTheme.isHidden | Boolean | Hide the current 4 steps view. |
progressTheme.backgroundColor | @ColorInt Int | Background color of the circle progress theme. |
progressTheme.progressColor | @ColorInt Int | Background color of the progress steps. |
gestureTheme.isHidden | Boolean | Whether of not should hide selfie steps' group view. |
gestureTheme.turnLeftActiveImage | Bitmap | Image for turn left step gesture when active. |
gestureTheme.turnRightActiveImage | Bitmap | Image for turn right step gesture when active. |
gestureTheme.turnUpActiveImage | Bitmap | Image for turn up step gesture when active. |
gestureTheme.turnDownActiveImage | Bitmap | Image for turn down step gesture when active. |
gestureTheme.lookStraightActiveImage | Bitmap | Image for look straight step gesture when active. |
gestureTheme.turnLeftInactiveImage | Bitmap | Image for turn left step gesture when inactive. |
gestureTheme.turnRightInactiveImage | Bitmap | Image for turn right step gesture when inactive. |
gestureTheme.turnUpInactiveImage | Bitmap | Image for turn up step gesture when inactive. |
gestureTheme.turnDownInactiveImage | Bitmap | Image for turn down step gesture when inactive. |
gestureTheme.lookStraightInactiveImage | Bitmap | Image for look straight step gesture when inactive. |
gestureTheme.finishedGestureBackgroundImage | Bitmap | Background for every step that completed. |
gestureTheme.currentStepFocusImage | Bitmap | Image overlay for current step indicator. |
maskViewErrorImage | Bitmap | The mask image of camera view when cannot detect any valid face. |
maskViewErrorImage | Bitmap | The mask image of camera view when cannot detect any valid face. |
loadingImage | Bitmap | Loading indicator in image. |
clone() | () -> TVSelfieCapturingTheme | A function that returns a deep copy of TVSelfieCapturingTheme's instance itself. |
Selfie Confirmation: UI customization

Class TVSelfieConfirmationTheme
If a property is not set then the default value will be used.
| Properties/Functions | Type | Description |
|---|---|---|
titleLabelTheme | TVLabelTheme | See Common UI components section. |
normalLabelTheme | TVLabelTheme | |
closeButtonLocation | enumTVButtonLocation | The position of close button to device orientation: .TOP_LEFT: to the left of the title .TOP_RIGHT: to the right of the title .NONE: hide the button |
showTrademark | Boolean | Show the trademark text or not. |
backgroundColor | @ColorInt Int | Background color of the screen. Default value is black with 60% opacity. |
closeButtonImage | Bitmap | The image of the close view button. |
maskViewImage | Bitmap | The mask image of selfie captured image. |
loadingImage | Bitmap | Loading indicator in image. |
clone() | () -> TVSelfieConfirmationTheme | A function that returns a deep copy of TVSelfieConfirmationTheme's instance itself. |
QR Popup: UI customization

Class TVQrPopupTheme
If a property is not set then the default value will be used.
| Properties/Functions | Type | Description |
|---|---|---|
titleLabelTheme | TVLabelTheme | See Common UI components section. |
descriptionTheme | TVLabelTheme | Theme of description text. |
primaryButtonTheme | TVLabelTheme | Theme of the main button of popup. |
secondaryButtonTheme | TVLabelTheme | Theme of sub-button of popup. |
timeoutLabelTheme | TVLabelTheme | Theme of timeout-warning text. |
backgroundColor | @ColorInt Int | Background color of the view. |
clone() | () -> TVQrPopupTheme | A function that returns a deep copy of TVQrPopupTheme's instance itself. |
Here is a snipped code example:
private TVTheme initTVTheme() {
TVTheme customizedTheme = new TVTheme();
// Selfie capturing screen
customizedTheme.getSelfieCapturingTheme().getGestureTheme().setLookStraightActiveImage(your_image);
// there are more to be customized...
// Selfie confirmation screen
customizedTheme.getSelfieConfirmationTheme().setRetryButtonImage(your_image);
// there are more to be customized...
// Id capturing screen
customizedTheme.getIdCapturingTheme().setMaskViewNeutralImage(your_image);
// there are more to be customized...
// Id confirmation screen
customizedTheme.getIdConfirmationTheme().setCloseButtonImage(your_image);
// there are more to be customized...
// QR guideline popup
customizedTheme.getQrGuidelinePopupTheme().setHeaderImage(your_image);
// there are more to be customized...
// QR guideline popup
customizedTheme.getQrRetryPopupTheme().setBackgroundColor(your_color);
// there are more to be customized...
return customizedTheme;
}