Scanning SDK
Scantrust Android SDK is the native sdk for the Scantrust Scan Engine.
Contents
- Contents
- Installation
- Getting Started
- FlowControllers And ScantrustCameraManager
- ReadOnlyCameraManager Setup and Management
- Location Management
- Utilities
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
- Android API 21+ is required as the
minSdkVersion
in most of our lib modules. - 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" />
- 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 itsonCreate
.
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 Activity
and 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.
CodeType | Description |
---|---|
QR | A 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. |
FP | A 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 Methods | Description |
---|---|
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 Methods | Description |
---|---|
public void setCodeParams(String message, int blurThreshBias, int activationStatus, int trainingStatus) | Sets the scanning parameters of a code. |
ScanTrustCameraManager:
Public Methods | Description |
---|---|
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 Context | Description |
---|---|
AUTH | Defines a scan that was made in the authentication context. |
CONTENT | Defines a scan that was not made for authentication. |
Processing Status: Defines the state of the flow
Processing Status | Description |
---|---|
COMPLETED_RESULT | Designs 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_PROGRESS | Designs 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_RESULT | Designs 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_RESULT | Indicates 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 State | Description |
---|---|
UNREADABLE | No QR code has been detected by the reader or the QR code that has been detected does not have all four required pattern centres |
OK | The code belongs to Scantrust and all the constraints are met |
TOO_SMALL | A code belonging to Scantrust has been detected, but the minimum size constraint has failed |
BLURRY | A code belonging to Scantrust has been detected, but has been classified as too blurry |
NOT_PROPRIETARY | A code has been detected, but it doesn't belong to Scantrust |
FP_NOT_IN_FRAME | A hybrid code belonging to Scantrust has been detected, but the external fingerprint zone is not in the frame |
NO_AUTH | A code with no authentication feature belonging to Scantrust has be found |
GLARE | A 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 Status | Code State | Quality Event | Description |
---|---|---|---|
COMPLETED_RESULT | OK | A code belonging to Scantrust has been detected and all is ok with it | |
NOT_PROPRIETARY | A code has been detected, but it doesn't belong to Scantrust | ||
NO_AUTH | A code with no authentication feature belonging to Scantrust has be found | ||
BLURRY | A code belonging to Scantrust has been detected, but has been classified as too blurry | ||
UNREADABLE | No 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_FRAME | A hybrid code belonging to Scantrust has been detected, but the external fingerprint zone is not in the frame | ||
TOO_SMALL | A code belonging to Scantrust has been detected, but the minimum size constraint has failed | ||
GLARE | A code belonging to Scantrust has been detected, but has been classified as having glare | ||
UNSUPPORTED_RESULT | UNREADABLE | No QR code has been detected by Zxing or the QR code that has been detected does not have all four required pattern centres | |
OK | The code belongs to Scantrust. The processing will be stopped | ||
NOT_PROPRIETARY | A code has been detected, but it doesn't belong to Scantrust. The processing will be stopped |
Scanning Context = AUTH
Processing Status | Code State | Quality Event | Description |
---|---|---|---|
COMPLETED_RESULT | OK | A scan is ready to be sent to the server for authentication | |
NOT_PROPRIETARY | A code has been detected, but it doesn't belong to Scantrust | ||
NO_AUTH | A code with no authentication feature belonging to Scantrust has be found | ||
IN_PROGRESS | OK | A scan of a code belonging to Scantrust has met all the constraints | |
BLURRY | A code belonging to Scantrust has been detected, but has been classified as too blurry | ||
UNREADABLE | No 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_FRAME | A hybrid code belonging to Scantrust has been detected, but the external fingerprint zone is not in the frame | ||
TOO_SMALL | A code belonging to Scantrust has been detected, but the minimum size constraint has failed | ||
GLARE | A code belonging to Scantrust has been detected, but has been classified as having glare | ||
UNSUPPORTED_RESULT | UNREADABLE | No QR code has been detected by Zxing or the QR code that has been detected does not have all four required pattern centres | |
OK | The code belongs to Scantrust. The processing will be stopped | ||
NOT_PROPRIETARY | A code has been detected, but it doesn't belong to Scantrust. The processing will be stopped | ||
BLOCKED_RESULT | OK or BLURRY or GLARE | TOO_BLURRY | The 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 GLARE | TIMEOUT_STRUGGLING | The 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_QUALITY | The 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_ACTIVITY | The 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 Formats | Format Type |
---|---|
Aztec | 2D barcode format |
CODABAR | 1D format |
Code 39 | 1D format |
Code 93 | 1D format |
Code 128 | 1D format |
Data Matrix | 2D barcode format |
EAN-8 | 1D format |
EAN-13 | 1D format |
ITF (Interleaved Two of Five) | 1D format |
MaxiCode | 2D barcode format |
PDF417 | |
QR Code | 2D barcode format |
RSS 14 | |
RSS EXPANDED | |
UPC-A | 1D format |
UPC-E | 1D format |
UPC/EAN | extension 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 Status | Code State | Description |
---|---|---|
COMPLETED_RESULT | OK | A code belonging to Scantrust has been detected (processing is paused) |
NOT_PROPRIETARY | A code has been detected, but it doesn't belong to Scantrust or is undetermined (processing is paused) | |
IN_PROGRESS | UNREADABLE | No 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.
- data: the output of the camera manager
- location: the location data obtained from the LocationHandlerThread or by your own means
- deviceInfo: the info about the device. This can be easily obtained with the static factory methods or by instantiating the
DeviceInfo
class. - 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 null
is 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.