Android Integration Guide

Importing DyScan

The easiest way to integrate DyScan is by using our Nexus repository, which is covered in this guide.

If you would rather include DyScan directly as a library, see the instructions here.

In the project-level build.gradle add the Dyneti Maven repository (credentials provided during integration):

allprojects {
    repositories {
        // Other repositories are here
        maven {
            credentials  {
                username = "nexusUsername"
                password = "nexusPassword"
            }
            url "https://nexus.dyneti.com/repository/maven-releases/"
            authentication {
                basic(BasicAuthentication)
            }
        }
    }
}

Default DyScan configuration includes the TensorFlow library. Since version 1.2.0, you can exclude it from DyScan if you prefer to use your own build of TensorFlow.

In the app-level build.gradle add the dependency:

dependencies {
    // Other dependencies are here
    implementation 'com.dyneti.android.dyscan:dyscan:1.5.1'
}

If you would rather integrate without using our Nexus repository, see Manually Importing the Library.

16 KB Page Size Support

Certain newer Android devices will begin using 16 KB page size. Dyneti has released version 1.7.14 which supports these devices.

To upgrade:

Change your implementation directive to use 1.7.14

implementation 'com.dyneti.android.dyscan_protect:dyscan:1.7.14')
or
implementation ('com.dyneti.android.dyscan:dyscan:1.7.14')
or
implementation 'com.dyneti.android.dyscan_protect:dyscan:1.7.14')

Gradle version 8.10 is required to build with support for 16 KB page size. Make sure the distributionUrl in gradle-wrapper.properties points to the correct version.

If you encounter the following error while building your project

Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.22 (org.jetbrains.kotlin:kotlin-stdlib:1.8.22) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)

Add the following dependency to your app-level build.gradle:

dependencies {
    // Fix duplicate class
    implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
}

Initializing DyScan (only for version 1.1.0 and up)

In your Application class add the following line to init DyScan.

public class DyScanApplication extends Application {

  //...

  @Override
  public void onCreate() {
    super.onCreate();
    //...
    DyScan.init(this, "{YOUR_API_KEY}");
    //...
  }
}

Camera features support

By default, DyScan uses uses-feature tags in its AndroidManifest.xml file to filter out devices that don't support the required camera features. This filtering affects the host app's supported device count in Google Play.

You can override this filtering by adding the below lines into your AndroidManifest.xml manifest tag section:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    ...

    <uses-feature android:name="android.hardware.camera" android:required="false" tools:replace="required" />
    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" tools:replace="required" />

    ...
</manifest>

If you choose to override the default tags settings inAndroidManifest.xml, you should additionally check manually if the device is supported before calling DyScan functions to avoid a bad user experience (see below).

if (DyScan.isDeviceSupported(context)) {
    // open DyScanActivity
    Intent intent = new Intent(context, DyScanActivity.class);
    startActivityForResult(intent, SCAN_REQUEST_CODE);
} else {
    // alternate flow if device is not supported
}

Interfacing DyScan

If your app already has card.io, see the migrating from card.io guide.

Import the following DyScan classes in your Activity that will launch DyScan:

import com.dyneti.android.dyscan.DyScanActivity;
import com.dyneti.android.dyscan.CreditCard;

This example assumes that you're going to launch the scanner from a button, and that you've set the button's onClick handler in the layout XML via android:onClick="onScanPress". (If not, the process is analogous, just use the code inside this function). onScanPress is implemented as

public void onScanPress(View v) {
    Intent scanIntent = new Intent(this, DyScanActivity.class);

    // for version lower than 1.1.0
    scanIntent.putExtra(DyScanActivity.EXTRA_API_KEY, "{api_key_string}");
    
    // MY_SCAN_REQUEST_CODE (e.g., 1337) is arbitrary and is only used within this activity.
    startActivityForResult(scanIntent, MY_SCAN_REQUEST_CODE);
}

Next, override onActivityResult() to get the scan result.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   super.onActivityResult(requestCode, resultCode, data);

   if (requestCode == MY_SCAN_REQUEST_CODE) {
       if (data != null && data.hasExtra(DyScanActivity.EXTRA_SCAN_RESULT)) {
           CreditCard scanResult = data.getParcelableExtra(DyScanActivity.EXTRA_SCAN_RESULT);
           // Do stuff with results in scanResult 
       }
   }
}

If you are using Stripe, see this guide for how to implement these functions.

The CreditCard class contains fields String cardNumber, int expiryMonth, int expiryYear, boolean isFraud, and String cardOrientation. For the OCR-only version of DyScan, isFraud is always set to false, and expiryYear is the full four-digit year.

Customizing DyScanActivity

The DyScanActivity can be customized by passing EXTRAs along with the intent. This allows you to modify both the appearance and behavior of the Activity.

If you want to have more control over the experience than DyScanActivity provides, we also offer a DyScanView.

Last updated