Skip to main content

Scanning SDK

Scantrust Android SDK is the native sdk for the Scantrust Scan Engine.

Contents

Installation

Include the sdk lib as a dependency

implementation 'com.scantrust.consumer:android-sdk:x.y.z'

Getting Started

The SDK offers the management of the camera, the image processing of the incoming frames and other features such as helpers for the api manager or utility functions.

Prerequisites

  1. Android API 21+ is required as the minSdkVersion in most of our lib modules.
  2. The SDK requires the following permissions and features (they don't necessarily need to be added into the app as they should already be in the individual libraries)
    • <uses-permission android:name="android.permission.CAMERA" />
    • <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    • <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    • <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    • <uses-feature android:name="android.hardware.camera" />
    • <uses-feature android:name="android.hardware.camera.autofocus" />
    • <uses-feature android:name="android.hardware.location.gps" />
  3. The scanning is meant to be done in the portrait phone orientation so the underlying Activity should therefore fix it (setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);) in its onCreate.

Prepare a Layout

The layout file of the scanning screen should include a FrameLayout or RelativeLayout that fills all the screen(match_parent) or as much as possible, to which a "preview" View will be added. The View will be provided either by the flow controller or directly by the ScanTrustCameraManager and needs to be added after instantiation.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:r="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<FrameLayout
android:id="@+id/preview_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</RelativeLayout>

FlowControllers And ScantrustCameraManager

The entry point of the SDK lib is either through one of the flow controllers or, in case a finer control is needed, through the ScanTrustCameraManager. These classes do all the heavy lifting; managing the scanning flow, setting up the camera and the preview view, running the image processing on the incoming frames and reporting the various outcomes.

The DoublePingFlowController should be the preferred choice.

  • It is based on the same flow as the "Three Steps" flow: The flow starts with the camera zoomed out and is in a state where it's waiting for a code to be scanned (step 1). If a code is read and is sufficiently centered (in a position that still makes it visible with the 4x zoom), then the zoom-in is done and the controller will be waiting for a code that meets the size constraint (step 2). Otherwise, the user will be told that he needs to center the code. As soon as a code meets the size constraint in the Fit QR state, the torch is turned on and as soon as the white balance is stabilised, the regular authentication process kicks in (step 3).
  • Requires extra code-dependent parameters: If no parameters are available for the current code, then the app will be notified that the controller is expecting them. If the code has encoded parameters in its content, then the flow will continue as in the three steps flow, if not, then the flow will be paused. As soon as new parameters are provided, if the code is not already known, then they get propagated to the quality processing part and are applied to the next frames.

Setup

DoublePingFlowController & ThreeStepsFlowController

Both controllers have two mandatory builder arguments: an Activity and a Callback for the reporting. They also have some optional arguments: a CropType which defines the type of crop to perform on the scan(fingerprint or QR code), a flag for the use or not in a QA app and a flag to indicate the state of the zoom when the manager is initialised. The default values for the optional parameters are: cropType = CropType.FP, isQa = false and startZoomedOut = true.

ScanTrustCameraManager

The ScanTrustCameraManager is obtained through it's builder which takes an Activityand a ManagerCallback for the reporting and that has four optional arguments: a CropType which defines the type of crop to perform on the scan(fingerprint or QR code), a flag for the use or not in a QA app, a flag to indicate the state of the zoom when the manager is initialised and a flag to indicate the need to obtain detailed content when not scanning for authentication. The default values for the optional parameters are: cropType = CropType.FP, isQa = false, startZoomedOut = true and detailedContent = false.

These classes should be instantiated in the creation phase of your screen. E.g. in the Activity's onCreate.

private DoublePingFlowController controller;    

@Override
public void onCreate(Bundle savedInstanceState) {
...
controller = new DoublePingFlowController.Builder(this, callback).build();

mPreviewLayout.addView(controller.getPreviewView());
...
}
private ScanTrustCameraManager cameraManager;    

@Override
public void onCreate(Bundle savedInstanceState) {
...
cameraManager = new ScanTrustCameraManager.Builder(this, managerCallback).build();

mPreviewLayout.addView(cameraManager.getPreviewView());
...
}

After instantiation, the View on which the frames are drawn is accessible with getPreviewView() and should be added to your Layout, as show in the example. The View is either a TextureView or a SurfaceView, depending on which version of the camera api is used.

Optional CropType And isQa Flag

Note: only the default values should normally be used.

CodeTypeDescription
QRA crop of the QR Code replaces the camera's frame (base image) in order to decrease the size of the server request. Notes: there is no crop image in the QRCodeData, the value of isQa is irrelevant and the values of the QR pattern centres are adapted to fit with the base image.
FPA crop of the secure graphic is added to the QRCodeData and the QR pattern centres and the crop offsets correspond to the crop. If the code is hybrid with SG outside AND isQa == false then the SG is outside of the QR and the crop is made accordingly. For all other cases, including hybrid with SG outside AND isQa == true, the crop is made in the centre of the QR.

Handling

The controller and manager give you access to the following methods. It is up to the user to determine when to start and stop the camera or the processing. But in general the camera is started in the onResume method and released in the onPause.

@Override
protected void onResume() {
...
cameraManager.startCamera();
...
}

@Override
protected void onPause() {
...
// Because the Camera object is a shared resource, it's very
// important to release it when the activity is paused.
cameraManager.releaseCamera();
...
}

ThreeStepsFlowController:

Public MethodsDescription
public View getPreviewView()Returns the View that was created by the manager and on which the camera preview is drawn.
public void startCamera()Starts the underlying camera object, its preview and starts the Scantrust frame processing.
public void releaseCamera()Releases the underlying camera object, stops the preview and stops the Scantrust frame processing.
public void restartProcessing()Restarts the Scantrust frame processing. Should be used when the frame processing has been paused. Note: this will not have an impact on the camera or its preview, but will restart the response flow.
public void pauseProcessing()Pauses the Scantrust frame processing. The flow of responses will stop, but the camera and it preview will not be affected.
public void setCameraTorchModeOnOff(boolean turnOn)Turns the torch on or off depending on the value of turnOn.
public void resetFlow()Resets the "three steps" flow.
public void doAutoFocus(float, float, int, int)Triggers a camera autofocus on the provided point. Usually only called in the onTouchListener associated to the preview view.

DoublePingFlowController:

Has the same methods as the ThreeStepsFlowController with the addition of:

Public MethodsDescription
public void setCodeParams(String message, int blurThreshBias, int activationStatus, int trainingStatus)Sets the scanning parameters of a code.

ScanTrustCameraManager:

Public MethodsDescription
public T getPreviewView()Returns the View that was created by the manager and on which the camera preview is drawn.
public void startCamera()Starts the underlying camera object, its preview and starts the Scantrust frame processing.
public void releaseCamera()Releases the underlying camera object, stops the preview and stops the Scantrust frame processing.
public void restartProcessing()Restarts the Scantrust frame processing. Should be used when the frame processing has been paused. Note: this will not have an impact on the camera or its preview, but will restart the response flow.
public void pauseProcessing()Pauses the Scantrust frame processing. The flow of responses will stop, but the camera and it preview will not be affected.
public void setCameraTorchModeOnOff(boolean turnOn)Turns the torch on or off depending on the value of turnOn.
public void resetZoom()Resets the "zoom-in" flow.
public void doZoomIn(Handler handler)Performs the automatic zooming-in if the camera is not already zoomed-in.
public boolean checkCodePositioning(QRCodeData data)Checks if the code is centered in the image
public void setScalingFactor(int physicalSize)Sets the scaling factor for the QR detection according to the given code physical size. As for the default setup, the size of the code should roughly be 108pix wide.
public void setAuthScanning(boolean scanForAuthentication)Triggers the processing for the authentication, as opposed to the processing for the content of the codes.
public boolean isZoomedOut()True if the camera zoomed-out.
public void doAutoFocus(float motionX, float motionY, int viewWidth, int viewHeight)Triggers a camera autofocus on the provided point. Usually only called in the onTouchListener associated to the preview view.

Results

The results are shared via a handler or a callback that comes as a constructor argument. The results are organised as follows:

Scanning Context: Defines the scan type

Scanning ContextDescription
AUTHDefines a scan that was made in the authentication context.
CONTENTDefines a scan that was not made for authentication.

Processing Status: Defines the state of the flow

Processing StatusDescription
COMPLETED_RESULTDesigns a response that needs special attention and therefore that has caused the Scantrust image processing to stop. The user will need to call restartProcessing() to restart the flow.
IN_PROGRESSDesigns a response that will not stop the Scantrust frame processing, the responses will keep coming as long as the user doesn't manually stop the flow or the camera or as long as a COMPLETED_RESULT or BLOCKED_RESULT doesn't occur.
UNSUPPORTED_RESULTDesigns a response obtained on an unsupported phone. The processing flow may or many not stop depending on the outcome of the scans. (should probably be in the report type rather than here...)
BLOCKED_RESULTIndicates a response obtained when the a quality event is triggered. The processing will stop.

Code State: Defines the state of the individual scans (found in the returned QRCodeData)

Code StateDescription
UNREADABLENo QR code has been detected by the reader or the QR code that has been detected does not have all four required pattern centres
OKThe code belongs to Scantrust and all the constraints are met
TOO_SMALLA code belonging to Scantrust has been detected, but the minimum size constraint has failed
BLURRYA code belonging to Scantrust has been detected, but has been classified as too blurry
NOT_PROPRIETARYA code has been detected, but it doesn't belong to Scantrust
FP_NOT_IN_FRAMEA hybrid code belonging to Scantrust has been detected, but the external fingerprint zone is not in the frame
NO_AUTHA code with no authentication feature belonging to Scantrust has be found
GLAREA code belonging to Scantrust has been detected, but has been classified as having glare

Quality Events: Define the events triggered by the capture quality manager. Note: the events live independently of the scan states

The scan states and quality events are distributed among the report types as shown in the following table:

Scanning Context = CONTENT

Processing StatusCode StateQuality EventDescription
COMPLETED_RESULTOKA code belonging to Scantrust has been detected and all is ok with it
NOT_PROPRIETARYA code has been detected, but it doesn't belong to Scantrust
NO_AUTHA code with no authentication feature belonging to Scantrust has be found
BLURRYA code belonging to Scantrust has been detected, but has been classified as too blurry
UNREADABLENo QR code has been detected by Zxing or the QR code that has been detected does not have all four required pattern centers. This is the only state in the CONTENT report type that doesn't stop the frame processing
FP_NOT_IN_FRAMEA hybrid code belonging to Scantrust has been detected, but the external fingerprint zone is not in the frame
TOO_SMALLA code belonging to Scantrust has been detected, but the minimum size constraint has failed
GLAREA code belonging to Scantrust has been detected, but has been classified as having glare
UNSUPPORTED_RESULTUNREADABLENo QR code has been detected by Zxing or the QR code that has been detected does not have all four required pattern centres
OKThe code belongs to Scantrust. The processing will be stopped
NOT_PROPRIETARYA code has been detected, but it doesn't belong to Scantrust. The processing will be stopped

Scanning Context = AUTH

Processing StatusCode StateQuality EventDescription
COMPLETED_RESULTOKA scan is ready to be sent to the server for authentication
NOT_PROPRIETARYA code has been detected, but it doesn't belong to Scantrust
NO_AUTHA code with no authentication feature belonging to Scantrust has be found
IN_PROGRESSOKA scan of a code belonging to Scantrust has met all the constraints
BLURRYA code belonging to Scantrust has been detected, but has been classified as too blurry
UNREADABLENo QR code has been detected by Zxing or the QR code that has been detected does not have all four required pattern centres
FP_NOT_IN_FRAMEA hybrid code belonging to Scantrust has been detected, but the external fingerprint zone is not in the frame
TOO_SMALLA code belonging to Scantrust has been detected, but the minimum size constraint has failed
GLAREA code belonging to Scantrust has been detected, but has been classified as having glare
UNSUPPORTED_RESULTUNREADABLENo QR code has been detected by Zxing or the QR code that has been detected does not have all four required pattern centres
OKThe code belongs to Scantrust. The processing will be stopped
NOT_PROPRIETARYA code has been detected, but it doesn't belong to Scantrust. The processing will be stopped
BLOCKED_RESULTOK or BLURRY or GLARETOO_BLURRYThe quality manager is reporting an important number of blurry scans. A scan (with a sufficient or reasonably insufficient quality) is available to be sent to the server. The processing will be stopped.
OK or BLURRY or GLARETIMEOUT_STRUGGLINGThe user has tried to scan for some time and is struggling. A scan (with a sufficient or reasonably insufficient quality) is available to be sent to the server. The processing will be stopped.
TIMEOUT_LOW_QUALITYThe user has tried to scan for some time, but the quality of the best frame is too poor to be sent to the server. The processing will be stopped.
TIMEOUT_LOW_ACTIVITYThe level of activity during the last portion of the scanning session is very low. The user has either given up or hardly no codes were detected in the frames. No scan is available and the processing will be stopped.

ReadOnlyCameraManager Setup and Management

The ReadOnlyCameraManager does the same camera and view setup as the ScanTrustCameraManager but does not perform the image and frame processing required for the Scantrust authentication. It is limited to checking the ownership of the code based on its content.

Setup

After instantiation, the View on which the frames are drawn is accessible with getSurfaceView() and should be added to your Layout.

The default builder takes an Activity and a ManagerCallback for the reporting.

public ReadOnlyCameraManager.Builder(Activity activity, ManagerCallback managerCallback)

It will enable the reading of 1D barcodes (UPC-A, UPC-E, EAN-8, EAN-13, Code 39, Code 93, Code 128, ITF(Interleaved Two of Five), RSS 14, RSS EXPANDED) and QR codes and its instantiation should be done in the same way as for the ScanTrustCameraManager.

Optional Arguments

An additional list of code formats can be provided as well as a tryHarder flag, which will optimize for accuracy over speed.

ReadOnlyCameraManager.Builder(activity, managerCallback).formatList(formats).tryHarder(true);
Available FormatsFormat Type
Aztec2D barcode format
CODABAR1D format
Code 391D format
Code 931D format
Code 1281D format
Data Matrix2D barcode format
EAN-81D format
EAN-131D format
ITF (Interleaved Two of Five)1D format
MaxiCode2D barcode format
PDF417
QR Code2D barcode format
RSS 14
RSS EXPANDED
UPC-A1D format
UPC-E1D format
UPC/EANextension format. Not a stand-alone format

Handling

The manager gives access to a subset of the ScantrustCameraManager methods and should be handled in the same way.

Results

The results are shared via a handler that comes as a constructor argument. The results obtained with the ReadOnlyCameraManager are:

Processing StatusCode StateDescription
COMPLETED_RESULTOKA code belonging to Scantrust has been detected (processing is paused)
NOT_PROPRIETARYA code has been detected, but it doesn't belong to Scantrust or is undetermined (processing is paused)
IN_PROGRESSUNREADABLENo code has been detected

Depending on the kind or Processing Status the frame processing will have been stopped from within the manager, refer to the tables for more information.

Location Management

In order to deal with the location updates in an asynchronous way, a LocationHandlerThread can be used. It extends HandlerThread so should be used in a similar way. It doesn't internally deal with the LOCATION permissions, so once instantiated, a Thread.UncaughtExceptionHandler should be added to it in order to catch the potential SecurityExceptions.

...
LocationHandlerThread locationHandler = new LocationHandlerThread(context, "LOCATION", Thread.NORM_PRIORITY);
locationHandler.setUncaughtExceptionHandler(exceptionHandler);
locationHandler.start();
...
}

Thread.UncaughtExceptionHandler exceptionHandler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
...
}
};

The LocationHandlerThread is started with start(), but the location updates will only start after having called resumeLocationUpdates(). The location updates can be stopped with pauseLocationUpdates() and the LocationHandlerThread itself should be stopped with quit() or quitSafely(). Managing the thread in the appropriate life-cycle methods is a good idea.

The latest location positions are obtained with getLocation().

Note: an underlying StLocationManager manages the location service and can be used by itself, but the user will then have to deal with the thread management. It uses the LocationManager to set up and obtain periodic updates of the device's geographical location according to Scantrust's needs. It requires the ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions and will throw SecurityExceptions if these permissions have not been granted or are disabled during use.

Utilities

PhoneCompatibilityManager

The compatibility manager is a utility class that is used to assess the phone's state/compatibility in relation to

  • Scantrust's Secure Graphic authentication (checkPhoneCompatibility)
  • NFC reading (checkNfcStatus)
  • Location(GPS, Network) availability (isLocationSupported)

NetworkUtils

Provides simple functions to determine the connectivity of the device.

Utils

Provides a helper method to get the install UUID

AuthRequestHelper & EnterpriseRequestHelper

For the calls that involve server authentication, the number of parameters to be sent is large and not very practical as the arguments require formatting. These two helper classes aim to make this formatting as easy as possible.

As a first step, interface methods using Retrofit2's @PartMap have been added to the consumer and enterprise apis. They give the possibility of adding the call parameters in a Map<String, RequestBody>. The AuthRequestHelper and EnterpriseRequestHelper are therefore helpers that populate this Map based on the output of the ScanTrustCameraManager and other available data.

//get code data from the camera manager
QrCodeData data = ...

//get the location data from the location manager
Location location = ...

//get the device IMEI
String imei = ...

//generate the map
Map<String, RequestBody> paramMap = new AuthRequestHelper().makeMapForAuth(
data,
location,
DeviceInfo.getDeviceInfo(imei),
AppInfo.getMobileAppInfo(context)
);

ApiManager.getAuthApi(apiBaseUrl).authenticate(
header1,
header2,
paramMap
).enqueue(new Callback<AuthResult>() {...});

Let's look at the arguments of makeMapForAuth(QRCodeData data, Location location, DeviceInfo deviceInfo, AppInfo appInfo) which is the helper function for the regular authentication.

  1. data: the output of the camera manager
  2. location: the location data obtained from the LocationHandlerThread or by your own means
  3. deviceInfo: the info about the device. This can be easily obtained with the static factory methods or by instantiating the DeviceInfo class.
  4. appInfo: the info about the app. Can be obtained with the Appinfo's static factory method or by instantiating the class.

The user may not have allowed the app to use geolocation, thus the function also exists without the location parameter and will produce the same output as if nullis provided (i.e. location.latitude = 0.0, location.longitude = 0.0 location.positioning = "").

The "android.permission.READ_PHONE_STATE" may also be denied which would prevent access to the phone's IMEI. The DeviceInfo class therefore has two constructors and relies on the developer to deal with the permissions. Note that providing the IMEI should be the standard way of doing, omitting it should only be for cases when the app is allowed to work without this info and should only be used if the user has explicitly rejected the permission.