Note This Java based version of the SDK Example has been superceded by a Kotlin version, which can be found here
Clone this repo and change directory to example
git clone https://github.com/vouched/vouched-android
cd vouched-android/example
Then, follow steps listed on the example README
- An account with Vouched
- Your Vouched Public Key
implementation 'id.vouched.android:vouched-sdk:1.2.0'
In order to use BarcodeDetect, you must add ML Kit Barcode Scanner.
Note: you can choose between the bundled and unbundled model. Our experience is that the bundled model provides more accurate barcode scans. See the above ML Kit link for more information
// Use this dependency to bundle the model with your app
implementation 'com.google.mlkit:barcode-scanning:17.0.2'
// Use this dependency to use the dynamically downloaded model in Google Play Services
implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:18.0'
In order to use FaceDetect, you must add ML Kit Face Detection.
Note: you can choose between the bundled and unbundled model. The unbundled model will provide a smaller app footprint, but will require connectivity to download the model when verification is run or when the app is first installed.
// Use this dependency to bundle the model with your app
implementation 'com.google.mlkit:face-detection:16.1.4'
// Use this dependency to use the dynamically downloaded model in Google Play Services
implementation 'com.google.android.gms:play-services-mlkit-face-detection:17.0.0'
This section will provide a step-by-step path to understand the Vouched SDK through the Example.
-
- Go through the verification process but stop after each step and take a look at the logs. Particularly understand the Job data from each verification step.
System.out.println(job.toJson());
- Once completed, take a look at the Job details on your Dashboard
-
Modify the Listeners
-
Locate the JobResponseListener in each Activity and make modifications.
- Add custom logic to display data or control the navigation
-
Locate the CardDetectResultListener and FaceDetectResultListener and add logging
-
-
Tweak CameraX settings
Better images lead to better results from Vouched AI -
You are ready to integrate Vouched SDK into your app
This class is introduced to make it easier for developers to integrate VouchedSDK and provide the optimal photography. The helper takes care of configuring the capture session, input, and output. Helper has following detection modes: 'ID' | 'FACE' | 'BARCODE' | 'ID_BACK'.
VouchedCameraHelper cameraHelper = new VouchedCameraHelper(this, this, ContextCompat.getMainExecutor(this), previewView, VouchedCameraHelper.Mode.ID, new VouchedCameraHelperOptions.Builder()
.withCardDetectOptions(new CardDetectOptions.Builder()
.withEnableDistanceCheck(false)
.withEnhanceInfoExtraction(false)
.withEnableOrientationCheck(false)
.build())
.withCardDetectResultListener(this)
.withBarcodeDetectResultListener(this)
.withCameraFlashDisabled(true)
.withTimeOut(3000, timeoutListener)
.build());
Parameter Type | Nullable |
---|---|
android.content.Context | false |
androidx.lifecycle.LifecycleOwner | false |
java.util.concurrent.Executor | false |
androidx.camera.view.PreviewView | false |
VouchedCameraHelper.Mode | false |
VouchedCameraHelper.Options | false |
Enhanced ID Info Extraction
The camera helper can increase your verification abilities by recognizing additional sources of information based on the type of ID that your user submits. You can enable this behavior by using .withEnhanceInfoExtraction(true)
when you create the camera helper.
Once enabled, the helper can help guide the ID verification modes by processing job results returned by the Vouched api service, and generating the appropriate modes that are needed to complete ID verification.
In terms of workflow, once the front ID has been imaged and uploaded, the Vouched service identifies the type if ID that is being used, and returns as part of response a JobResult object that informs the SDK as to other data extraction actions that may be taken. These additional actions can include extractions of data from one or more barcodes or capturing an image of the back of the ID for firther analysis.
In the current release, some coding is necessary - in your JobResponseListener callback, you first must verify that the job has no errors or insights (user feedback that requires more actions on the user's part before leaving a mode). If that proves to be true, pass the camera helper the results object and determine the next mode. Since you know what the next mode will be, this is a great point to dispay a dialog or provide other feedback to the user as to inform them as what to expect next.
onJobResonse changes:
// after verifying errors and insights, determine if the
// ID requires other processing
cameraHelper.updateDetectionModes(job.getResult());
// advance the mode to the next state.
VouchedCameraHelper.Mode next = cameraHelper.getNextMode();
// give the user feedback based on the next step
onCardDetectResult changes for back/frontside detection:
VouchedCameraHelper.Mode currentMode = cameraHelper.getCurrentMode();
if(currentMode.equals(VouchedCameraHelper.Mode.ID)) {
session.postFrontId(this, cardDetectResult, new Params.Builder().withFirstName(inputFirstName).withLastName(inputLastName), this);
} else if(currentMode.equals(VouchedCameraHelper.Mode.ID_BACK)) {
session.postBackId(this, cardDetectResult, null, this);
}
Note: The DetectorActivityWithHelper class in the example app shows how enhanced extraction can be implemented.
Enabling distance check
The camera helper can find for an ideal distance to capture the photo of the document by using .withEnableDistanceCheck(true)
when setting you create the camera helper.
When this is enabled, the helper will guide us through instructions (passed through an OnDetectResultListener set by VouchedCameraHelperOptions.Builder.withCardDetectResultListener(OnDetectResultListener cardDetectResultListener)
) so that the user can move near or far his document from the camera.
Enabling orientation check
The camera helper can assist in guiding the user to an ideal ID document orientation by using .withEnableOrientationCheck(true)
when setting you create the camera helper.
When this is enabled, the helper will guide the user through instructions (passed through an OnDetectResultListener set by VouchedCameraHelperOptions.Builder.withCardDetectResultListener(OnDetectResultListener cardDetectResultListener)
), so that the user can rotate their ID document to match the desired orientation.
Adding a timeout to ID scan
It is possible to set a timeout for how long to wait until an ID is captured, by using VouchedCameraHelperOptions.Builder.withTimeOut(Long timeInMilliseconds, TimeoutListener listener)
(see TimeoutListener). When the timer expires the helper will stop looking for the ID, at which point it is possible to give the user the option to retry using vouchedCameraHelperInstance.clearAndRestartTimeout()
or to manually capture the photo of his document using vouchedCameraHelperInstance.capturePhoto(imageCaptureListener)
(see ImageCaptureListener).
We recommend using CameraX with the Vouched SDK. The references will all use CameraX, and in the case of the VouchedCameraHelper, the CameraX apis are a dependency of that component.
This class handles a user's Vouched session. It takes care of the API calls. Use one instance for the duration of a user's verification session.
VouchedSession session = new VouchedSession("PUBLIC_KEY");
Parameter Type | Nullable |
---|---|
String | false |
VouchedSession session = new VouchedSession("PUBLIC_KEY", new VouchedSessionParameters.Builder().withToken("TOKEN").build());
session.postFrontId(this, cardDetectResult, new Params.Builder(), this);
Parameter Type | Nullable |
---|---|
android.content.Context | false |
CardDetectResult | false |
ParamsBuilder | true |
JobResponseListener | false |
session.postFace(this, faceDetectResult, new Params.Builder(), this);
Parameter Type | Nullable |
---|---|
android.content.Context | false |
FaceDetectResult | false |
ParamsBuilder | true |
JobResponseListener | false |
session.confirm(this, null, this);
Parameter Type | Nullable |
---|---|
android.content.Context | false |
ParamsBuilder | true |
JobResponseListener | false |
This class handles detecting an ID (cards and passports) and performing necessary steps to ensure image is POSTABLE.
CardDetect cardDetect = new CardDetect(getAssets(), new CardDetectOptions.Builder().withEnableDistanceCheck(true)
.withEnhanceInfoExtraction(false)build(), this);
Parameter Type | Nullable |
---|---|
android.content.res.AssetManager | false |
CardDetectOptions | false |
CardDetect.OnDetectResultListener | false |
cardDetect.processImageProxy(imageProxy, handler);
Parameter Type | Nullable |
---|---|
androidx.camera.core.ImageProxy | false |
android.os.Handler | false |
This class handles detecting the encoded barcode data. Only applicable for ID and DL cards.
BarcodeDetect barcodeDetect = new BarcodeDetect(this);
Parameter Type | Nullable |
---|---|
BarcodeDetect.OnBarcodeResultListener | false |
cardDetect.findBarcode(imageProxy);
Parameter Type | Nullable |
---|---|
androidx.camera.core.ImageProxy | false |
This class handles detecting a face and performing necessary steps to ensure image is POSTABLE.
FaceDetect faceDetect = new FaceDetect(this, new FaceDetectOptions.Builder().withLivenessMode(LivenessMode.DISTANCE).build(), this);
Parameter Type | Nullable |
---|---|
android.content.Context | false |
FaceDetectOptions | false |
FaceDetect.OnDetectResultListener | false |
faceDetect.processImageProxy(imageProxy, graphicOverlay);
Parameter Type | Nullable |
---|---|
androidx.camera.core.ImageProxy | false |
GraphicOverlay | true |
The output from Card Detection and used to submit an ID. Note that CardDetectResults can arise from scanning the font or back of certain ID documents. It is currently the responsibility of the card detection callback to keep track of the mode the helper is in, and post to the correct endpoint. A future update will remove this requirement.
class CardDetectResult {
public Step getStep() { ... }
public Instruction getInstruction() { ... }
public String getImage() { ... }
public String getDistanceImage() { ... }
}
An example of handling front and back ID images in a card detection callback:
VouchedCameraHelper.Mode currentMode = cameraHelper.getCurrentMode();
if(currentMode.equals(VouchedCameraHelper.Mode.ID)) {
session.postFrontId(this, cardDetectResult, new Params.Builder().withFirstName(inputFirstName).withLastName(inputLastName), this);
} else if(currentMode.equals(VouchedCameraHelper.Mode.ID_BACK)) {
session.postBackId(this, cardDetectResult, null, this);
}
An enum to provide detection modes for VouchedCameraHelper
enum Mode {
ID,
BARCODE,
ID_BACK,
FACE,
COMPLETED
}
List of options to alter image processing for VouchedCameraHelper
VouchedCameraHelperOptions cameraOptions = new VouchedCameraHelperOptions.Builder()
.withFaceDetectOptions(new FaceDetectOptions.Builder()
.withLivenessMode(LivenessMode.MOUTH_MOVEMENT)
.build())
.withFaceDetectResultListener(this)
.build());
The output from Barcode Detection and used to submit the encoded Barcode data.
class BarcodeResult {
public String getValue() { ... }
public String getImage() { ... }
}
The output from Face Detection and used to submit a Selfie.
class FaceDetectResult {
public Step getStep() { ... }
public Instruction getInstruction() { ... }
public String getImage() { ... }
public String getUserDistanceImage() { ... }
}
The builder for the parameters that are used to submit a Job.
class Builder {
public Builder withFirstName(String firstName) { ... }
public Builder withLastName(String lastName) { ... }
public Builder withIdPhoto(String idPhoto) { ... }
public Builder withUserPhoto(String userPhoto) { ... }
public Builder withUserDistancePhoto(String userDistancePhoto) { ... }
public Builder withIdDistancePhoto(String idDistancePhoto) { ... }
public Params build() { ... }
}
The listener to retrieve the Job data from the submission.
public interface OnJobResponseListener {
void onJobResponse(JobResponse response);
}
Follow the below template
@Override
public void onJobResponse(JobResponse response) {
if (response.getError() != null) {
// handle app/network/system errors
} else { // see if there are recoverable job errors
Job job = response.getJob();
List<Insight> insights = VouchedUtils.extractInsights(response.getJob());
// inform the user of the error extracted
}
// implement business and navigation logic based on Job data
}
The options for Card Detection.
class Builder {
public Builder withEnableDistanceCheck(boolean enableDistanceCheck) { ... }
public Builder withEnhanceInfoExtraction(boolean enableEnhancedIdScan) { ... }
public Builder withEnableOrientationCheck(boolean enableOrientationCheck) { ... }
public CardDetectOptions build() { ... }
}
The listener to retrieve CardDetectResult.
interface OnDetectResultListener {
void onCardDetectResult(CardDetectResult cardDetectResult);
}
The listener to retrieve BarcodeDetectResult.
interface OnBarcodeResultListener {
void onBarcodeResult(BarcodeResult barcodeResult);
}
Listener to know when the timeout has expired when a document is being scanned, when this is executed the helper stops searching for documents or barcodes.
interface TimeoutListener {
void onTimeout();
}
listener to know when a photo has been captured manually
interface ImageCaptureListener {
void onImageCapture(Bitmap bitmap);
}
The options for Face Detection.
public enum LivenessMode {
MOUTH_MOVEMENT,
DISTANCE,
BLINKING,
NONE
}
class Builder {
public Builder withLivenessMode(LivenessMode livenessMode) { ... }
public FaceDetectOptions build() { ... }
}
The listener to retrieve FaceDetectResult.
interface OnDetectResultListener {
void onFaceDetectResult(FaceDetectResult faceDetectResult);
}
An enum to provide an optional baseline of Verification Error(s) for a given Job.
enum RetryableError {
InvalidIdPhotoError,
InvalidUserPhotoError,
BlurryIdPhotoError,
GlareIdPhotoError
}