Mobile App (Android)

The first thing you'll need to build a native Android app for document verification is Acuant's Android SDK:

Prerequisite Knowledge

Before starting this guide, you should be comfortable with the following tools and technologies:

  • Trulioo’s API (especially Document Verification)
  • Java
  • Android application development & Android Studio
  • Gradle
  • Git (optional, but preferred)

Setup Overview

To implement an Android document capture application, you'll need to go through the following steps, each of which has its own detailed section below:

  1. Clone the Acuant Android repository
  2. Import the project into Android Studio
  3. Run the Acuant sample app
  4. Import Trulioo's sample app into Android Studio
  5. Run Trulioo's sample application to make an initial document verification test
  6. Use TruliooVerify.java alongside Acuant’s Android SDK to build a full document verification application

Android Setup

The SDK will need both an environment and a device to run on:

  1. Install Android Studio.
  2. Device requirements:
    • Android SDK 17 or later.
    • 5MP Camera or higher
  3. Follow the steps at here. This will allow your device to run applications from Android Studio.

Running the Acuant Sample App

The following is taken from Preparing to install the Acuant Android Mobile SDK:

  1. Create a new directory, on the command line:
mkdir DocumentVerificationApp
  1. On the command line change into that directory:
cd DocumentVerificationApp
  1. To get the code itself from git, on command line run
git clone https://github.com/Acuant/AcuantAndroidMobileSDK.git

(Alternatively download the zip file from https://github.com/Acuant/AcuantAndroidMobileSDK).
4. Open Android Studio installed from the [#setup overview] section.
5. Select “Open File or Project”. Navigate to the directory where you cloned Acuant’s SDK and select “AcuantAndroidMobileSDK-master\AcuantAndroidMobileSampleSDK”.

459

Open File or Project

  1. The Project will build automatically (Note: if there’s a build error, select Build -> Make Project).
323

Make Project

  1. Once built successfully connect your device to your computer via usb, enable USB debugging as per step #3 in the Android Setup section.
  2. Select Run -> Run 'Sample-App'.
524

Run 'Sample-App'

This will run the standalone Acuant Sample App but will not be able to verify any documents.

Running the Trulioo Prototype App

Trulioo provides a sample application built on top of Acuant's which incorporates calls to Trulioo's own document verification endpoints. The exact changes made in Trulioo's sample app will be outlined in detail in the next section. To run the application:

  1. Create a new directory on the command line:
mkdir TruliooDemoApp
  1. Navigate into that directory:
cd TruliooDemoApp
  1. Run:
git clone https://github.com/Trulioo/prototype-document-verification-app-v1.git

Alternatively, you can download the Trulioo sample app directly here.
4. Open Android Studio, which you should have installed in the android setup section.
5. Select “Open File or Project”.
6. Navigate to the “TruliooDemoApp” directory containing the sample code you just downloaded and select “AcuantAndroidMobileSDK-master\AcuantAndroidMobileSampleSDK”.
7. The project will build automatically (if there’s a build error, select Build -> Make Project).
8. In the class MainActivity.java, navigate to the method initializeSDK(). Replace the variable licenceKey with the Acuant key provided to you by Trulioo.
9. Connect your device to your computer via USB and enable USB debugging as per step #3 in the Android Setup section.
10. Select Run -> Sample-App.
11. Enter your Trulioo API credentials on the initial application screen.

Behind the Trulioo Prototype App

If you're curious about how exactly the Trulioo prototype app works, this section contains a detailed walkthrough of its classes and methods.

TruliooVerify.java

This class handles the interaction between the application and Trulioo’s API.

Authenticate

There are three calls in TruliooVerify that are used for authentication. The first two are simple setters:

void setUsername(String userName) {}
void setPassword(String psswrd) {}

These methods are called when you first enter your Trulioo API credentials. There’s also a method to check these credentials are valid, which is only called once the username and password have been set during login:

boolean isAuthenticated()

This calls the Test Authentication method in Trulioo’s API. It runs as an AsyncTask, so it shouldn’t cause any Android threading issues.

Document Image Setters

These methods are used to set the fields that will be sent from the document capture application to Trulioo:

void setTruliooFront(byte[] tFront) {}
void setTruliooBack(byte[] tBack) {}
void setTruliooSelfie(byte[] tSelfie) {}

These methods set the documentFrontImage, documentBackImage and LivePhoto images. The LivePhoto or Selfie is an optional addition where the user takes a photo of themselves to be compared against the document image. All 3 of these methods take a byte array, which can be obtained directly from a bitmap by using the bitmapToByteArray method below in the Helper Methods.

Depending on your configuration the selfie or document back image may be optional, use Get Fields to determine what's required. The images must be sent to Trulioo as Base64 - encoded strings, but this is handled for you in the verify call (discussed below).

To set the document type being verified you can use the following method. Examples include "Passport" and "DrivingLicence". Use Get Document Types to see what Documents you are configured for in a given country:

void setDocument(String docType) {}

To set the first and last name of the individual being verified:

void setFirstName(String fName) {}
void setSurname(String sName) {}

To set the ISO 3166-1 alpha-2 country code for the verification:

void setCountry(String countryCode) {}

Note: You can obtain the full list of country codes to which your account has access through the Get Country Codes endpoint. In the Trulioo sample app, this endpoint is used this to populate a user input field where they can select the correct country.

Apart from setTruliooBack() and setTruliooSelfie(), all of the setter methods above must be called in order to perform a successful verification. Depending on your configuration, you may have to call setTruliooBack() and/or setTruliooSelfie() as well.

Helper Methods

The TruliooVerify class has three helper methods. Since the setTruliooFront/Back/Selfie methods accept a byteArray, it TruliooVerify offers a built-in helper which produces a byteArray from a bitmap:

byte[] bitmapToByteArray(Bitmap bmp) {}

Each verification request is associated with a specific country code, and this country code must be enabled for your account. In order to get a fully up-to-date list of available countries for your account, it is recommended to always call the Get Country Codes method. The Trulioo document verification app provides a helper for this, abstracting away the work of creating and processing the request/response:

List<String> getCountryCodes() {}

Finally, there is a method that saves the provided image to the user's phone gallery. This could be integrated into your application as a save button, if requested:

void saveImgToGallery(Bitmap img, String name, Context context) {}

Verify

Once the images have been captured and the fields have been set, the actual document verification request can be made. The verify() method uses the values you've set to construct the Verify request for you. The API call is executed as an AsyncTask. If the verification is successful, the method will return the transactionRecordID, which can later be used to view this transaction in Trulioo's portal or Get Transaction Record endpoint.

String verify() {}

Build.gradle

The build.gradle file contains several dependencies. The first is Trulioo’s Java SDK distributed as an aar Android Library.

compile (name: 'normalizedapi-debug-1.0.0', ext: 'aar')

Other dependencies that need to be included are, for networking purposes:

compile ('com.squareup.okhttp3:okhttp:3.8.0')

For manipulating and working with JSON:

compile ('com.google.code.gson:gson:2.8.0')

And, for date and time handling:

compile 'joda-time:joda-time:2.9.9'

Changes to Acuant's Sample App

This section gives a detailed explanation of the changes that have been made to Acuant's sample app to turn it into Trulioo's document verification prototype application.

Login Screen

  • activity_main.xml – Added 2 editTexts, one for username and one for password, and a login button.
<EditText
	android:id="@+id/username"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:ems="10"
	android:hint="@string/username"
	android:inputType="text"
	android:selectAllOnFocus="true"
	android:singleLine="false"
	android:textColor="@color/TruliooBlue"
	android:textColorHint="@color/TruliooBlue"
	android:textSize="14sp" />

<EditText
	android:id="@+id/password"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:ems="10"
	android:hint="@string/password"
	android:inputType="textPassword"
	android:selectAllOnFocus="true"
	android:singleLine="false"
	android:textColor="@color/TruliooBlue"
	android:textColorHint="@color/TruliooBlue"
	android:textSize="14sp" />

<Button
	android:id="@+id/loginButton"
	style="@style/Widget.AppCompat.Button"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:backgroundTint="@color/TruliooBlue"
	android:elevation="8dp"
	android:onClick="truliooLogin"
	android:text="Login"
	android:textSize="18sp"
	android:translationZ="8dp" />
  • MainActivity.java - Added the method truliooLogin, which will be triggered by the loginButton above. This method includes the setting of username and password before the isAuthenticated call is made. If the user is authenticated, the method hides all of the login functionality and displays the full verification UI:
public void truliooLogin(View v){
        truliooVerify.setUsername(usernameEditText.getText().toString());
        truliooVerify.setPassword(passwordEditText.getText().toString());
        Button loginButton = (Button) findViewById(R.id.loginButton);
        if(truliooVerify.isAuthenticated()){
            buttonDL.setVisibility(View.VISIBLE);
            buttonPassport.setVisibility(View.VISIBLE);
            firstNameEditText.setVisibility(View.VISIBLE);
            secondNameEditText.setVisibility(View.VISIBLE);
            usernameEditText.setVisibility(View.GONE);
            passwordEditText.setVisibility(View.GONE);
            loginButton.setVisibility(View.GONE);
            relativeLayoutFrontImage.setVisibility(View.VISIBLE);
            processCardButton.setVisibility(View.VISIBLE);
            authenticated = true;
            initializeSpinner();
            countrySpinner.setVisibility(View.VISIBLE);
          //  updateUI();
        } else{
            Toast.makeText(this, "Password/Username Invalid", Toast.LENGTH_SHORT).show();
        }
    }
  • The medical card tab is not supported and so it has been removed.
  • The confirmation screen has been updated to include copy of the best practices for image capture. This is for the individual being verified (i.e. the user taking the picture) to be able to run a manual check of the image quality before sending it for verification.
    • image_confirmation.xml –replace the TextView with the following:
<TextView
	android:id="@+id/messageTextView"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_alignParentStart="false"
	android:layout_centerHorizontal="true"
	android:layout_marginBottom="30dip"
	android:gravity="left|center"
	android:text="@string/img_confirm"
	android:textAlignment="textStart"
	android:textAllCaps="false"
	android:textColor="@color/TruliooBlue"
	android:textSize="18sp" />
* acuantStrings.xml – Added the following line:
<string name="img_confirm">Check for the following and retry if present:\n-Any text not readable.\n-Anything blocking the image.\n-Blurry photo.\n-Glare spot on id.</string>
  • For branding purposes the colours on each of the elements were changed. Colors.xml – There are 4 variables set here to define colours throughout the prototype:
<color name="TruliooBlue">#1ba5ea</color>
<color name="TruliooBlueBar">#0F5A7F</color>
<color name="TruliooGreen">#aed644</color>
<color name="TruliooBackground">#ffffff</color>
  • For the user to be able to enter information about themselves, extra fields were added. activity_main.xml - Added first name, surname and country code fields to allow data entry:
<EditText
	android:id="@+id/editTextFirst"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:ems="10"
	android:hint="@string/first_name"
	android:inputType="textCapSentences"
	android:selectAllOnFocus="true"
	android:singleLine="false"
	android:textColor="@color/TruliooBlue"
	android:textColorHint="@color/TruliooBlue"
	android:textSize="14sp"
	android:visibility="invisible" />

<EditText
	android:id="@+id/editTextSecond"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:ems="10"
	android:hint="@string/second_name"
	android:inputType="textCapSentences"
	android:selectAllOnFocus="true"
	android:singleLine="false"
	android:textColor="@color/TruliooBlue"
	android:textColorHint="@color/TruliooBlue"
	android:textSize="14sp"
  android:visibility="invisible" />

<Spinner
	android:id="@+id/spinnerCountry"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:background="@color/TruliooBlue"
	android:textColor="@color/TruliooBlue"
	android:visibility="invisible" />
  • MainActivity.java - Added method to populate the countries spinner:
private void initializeSpinner(){
    List<String> countryList = truliooVerify.getCountryCodes();
    String[] spinnerArray = new String[countryList.size()];
    spinnerArray = countryList.toArray(spinnerArray);
    countrySpinner = (Spinner) findViewById(R.id.spinnerCountry);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, spinnerArray);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    countrySpinner.setAdapter(adapter);
}
  • The call to verify needed to be updated so that it no longer calls Acuant’s API but Trulioo’s. activity_main - Updated the process button to call the Trulioo processing method as opposed to Acuant's.
<Button
	android:id="@+id/processCardButton"
	style="@style/Widget.AppCompat.Button"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:backgroundTint="@color/TruliooBlue"
	android:elevation="8dp"
	android:onClick="initiateTruliooProcessing"
	android:text="@string/process"
	android:textSize="18sp"
	android:translationZ="8dp"
	android:visibility="visible" />
  • MainActivity.java – Added the Trulioo processing method called above to start the image capture:
public void initiateTruliooProcessing(View v) {
        if(!firstNameEditText.getText().toString().isEmpty() && !secondNameEditText.getText().toString().isEmpty()) {
            if (isFacialFlow) {
                if (mainActivityModel.getCurrentOptionType() == CardType.FACIAL_RECOGNITION || mainActivityModel.getCurrentOptionType() == CardType.PASSPORT || mainActivityModel.getCurrentOptionType() == CardType.DRIVERS_LICENSE) {
                    isProcessingFacial = true;
                    processCardButton.setVisibility(View.INVISIBLE);
                    relativeLayoutFrontImage.setVisibility(View.INVISIBLE);
                    if(mainActivityModel.getCurrentOptionType() == CardType.DRIVERS_LICENSE) relativeLayoutBackImage.setVisibility(View.INVISIBLE);
                    showFacialDialog();
                }
            }
            if (!isProcessingFacial) {
                if (progressDialog != null && progressDialog.isShowing()) {
                    Util.dismissDialog(progressDialog);
                }
                progressDialog = Util.showProgessDialog(MainActivity.this, "Capturing data ...");
                Util.lockScreen(this);
            }
        }
    }
  • MainActivity.java – Added another processing method for when the facial capture activity returns successfully, which sets all the required values and ultimately calls the verify() method:
private void processTruliooRequest(final Bitmap bitmap){
        progressDialog.dismiss();
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            public void run()
            {
                processCardButton.setVisibility(View.INVISIBLE);
                relativeLayoutFrontImage.setVisibility(View.INVISIBLE);
                if(mainActivityModel.getCurrentOptionType() == CardType.DRIVERS_LICENSE) relativeLayoutBackImage.setVisibility(View.INVISIBLE);
            }
        });
        BitmapDrawable drawable = (BitmapDrawable) frontImageView.getDrawable();
        Bitmap frontImage = drawable.getBitmap();
        byte[] frontByteArray = truliooVerify.bitmapToByteArray(frontImage);
        truliooVerify.setTruliooFront(frontByteArray);

        BitmapDrawable back_drawable = (BitmapDrawable) backImageView.getDrawable();
        if(back_drawable!=null) {
            Bitmap backImage = back_drawable.getBitmap();
            byte[] backByteArray = truliooVerify.bitmapToByteArray(backImage);
            truliooVerify.setTruliooBack(backByteArray);
        }

        byte[] selfieByteArray = truliooVerify.bitmapToByteArray(bitmap);
        truliooVerify.setTruliooSelfie(selfieByteArray);
        String strSelfie = MediaStore.Images.Media.insertImage(this.getContentResolver(), bitmap, UUID.randomUUID().toString(),"description");

        System.out.println("username: " + usernameEditText.getText());
        System.out.println("password: " + passwordEditText.getText());

        truliooVerify.setUsername(usernameEditText.getText().toString());
        truliooVerify.setPassword(passwordEditText.getText().toString());

        switch ( mainActivityModel.getCurrentOptionType()){
            case 0:
                truliooVerify.setDocument("DrivingLicence");
                break;
            case 2:
                truliooVerify.setDocument("Passport");
                break;
        }

        truliooVerify.setFirstName(firstNameEditText.getText().toString());
        truliooVerify.setSurname(secondNameEditText.getText().toString());
        truliooVerify.setCountry(countrySpinner.getSelectedItem().toString());

        String verifyString = truliooVerify.verify();
        Handler refresh = new Handler(Looper.getMainLooper());
        refresh.post(new Runnable() {
            public void run()
            {
                progressBar.setVisibility(View.INVISIBLE);
                processCardButton.setVisibility(View.VISIBLE);
                relativeLayoutFrontImage.setVisibility(View.VISIBLE);
                if(mainActivityModel.getCurrentOptionType() == CardType.DRIVERS_LICENSE) relativeLayoutBackImage.setVisibility(View.VISIBLE);
            }
        });
        confirmDialog(verifyString);
    }

Barcode Scanning

For US and Canadian Licences The SDK also provides a way to scan the licence barcode and read the data contained. It is described in full detail here: https://github.com/Acuant/AcuantAndroidMobileSDK#show-the-barcode-camera-methods