SDK reference · Android SDK / Android Getting Started

Installation

This page covers everything you need to add the Incode Android SDK to your project. It covers build requirements, repository and dependency setup with Gradle, the Incode Bill of Materials (BOM), required and optional permissions, initializing the SDK, and enabling test mode. After the project builds, choose an integration approach.


Build Requirements

Ensure your build environment meets the following minimum requirements:

  • Java: Java 8 in your module-level [module]/build.gradle, applied to both sourceCompatibility and targetCompatibility. This page explains where to set this.
  • compileSdk: 35 or higher. The SDK's bundled AndroidX dependencies require apps to compile against API 35 or later. If your compileSdk is lower, the build fails the AAR-metadata check with ... require ... compile against version 35 or later. Set compileSdk 35 or higher in your module-level build.gradle. This is independent of minSdk and targetSdk.
  • minSdk: 23; raise to 24 if you use video-streaming. Raise to 28 if you use Google Wallet.
  • targetSdk: Your choice; the SDK itself targets API 33.
  • Build tooling: Android Gradle Plugin 8.6.0, Gradle 8.7, Kotlin 1.9.25. Newer compatible versions also work. Matching your Android Studio's bundled AGP avoids IDE sync slowdowns.

Also, ensure your devices meet the device requirements. Then complete the following steps in order.


Add Repositories

The Incode Android SDK is distributed through GitHub Packages. To receive credentials, contact your enterprise customer success manager or help@incode.com.

Warning

Artifactory Distribution Has Ended

Support for Artifactory distribution ended September 19, 2025. If you are using Artifactory in your production integration, migrate to GitHub Packages to maintain uninterrupted access to the SDK.

The code blocks below use the project-level build.gradle. On projects that use Gradle's centralized repository management, which is the default for newer Android Studio projects, add the same repositories { } entries to the dependencyResolutionManagement block in settings.gradle instead. The URLs and credentials are identical. If you keep them in the project build.gradle, make sure settings.gradle is not set to RepositoriesMode.FAIL_ON_PROJECT_REPOS.

Add the GitHub Packages Repository

Add the following to your project-level build.gradle. For more information about declaring repositories, see the Gradle documentation.

repositories {
    maven {
        url "https://maven.pkg.github.com/Incode-Technologies-Example-Repos/android-omni-packages"
        credentials {
            username = "incode-customers"
            password = "YOUR_GITHUB_TOKEN"
        }
    }
}
repositories {
    maven {
        url = uri("https://maven.pkg.github.com/Incode-Technologies-Example-Repos/android-omni-packages")
        credentials {
            username = "incode-customers"
            password = "YOUR_GITHUB_TOKEN"
        }
    }
}

Keep username as incode-customers. Replace YOUR_GITHUB_TOKEN with the access token Incode provides. The token must have the read:packages scope and access to the android-omni-packages registry, or dependency resolution fails with 401 Unauthorized. Do not commit the token. Store it outside source control—for example, in ~/.gradle/gradle.properties or an environment variable—and read it in:

credentials {
    username = "incode-customers"
    password = providers.gradleProperty("incode.githubToken").get()
}

Add the JitPack Repository

The SDK depends on JitPack. Add the following Maven repository.

repositories {
    maven { url "https://jitpack.io" }
}
repositories {
    maven("https://jitpack.io")
}

Add Google and Maven Central

If the Google and Maven Central repositories are not already in your project-level build.gradle file, add them.

repositories {
    google()
    mavenCentral()
}
repositories {
    google()
    mavenCentral()
}

Combined, your project-level repositories should look like this:

repositories {
    google()
    mavenCentral()

    maven { url "https://jitpack.io" }
    maven {
        url "https://maven.pkg.github.com/Incode-Technologies-Example-Repos/android-omni-packages"
        credentials {
            username = "incode-customers"
            password = "YOUR_GITHUB_TOKEN"
        }
    }
}
repositories {
    google()
    mavenCentral()

    maven("https://jitpack.io")
    maven {
        url = uri("https://maven.pkg.github.com/Incode-Technologies-Example-Repos/android-omni-packages")
        credentials {
            username = "incode-customers"
            password = "YOUR_GITHUB_TOKEN"
        }
    }
}

Enforce Java 8

Add the following code inside your android{} block in your [module]/build.gradle. [module] refers to your app or library module, not an Incode SDK module.

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
compileOptions {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

Add the Incode Bill of Materials (BOM)

The Incode BOM streamlines dependency version control. When you specify the BOM's version, it automatically ensures all Incode dependencies in your project use compatible versions. You don't need to assign versions to each dependency individually. Update the BOM version to update all dependencies at once. See BOM Version Mapping for the latest version.

Specifying the BOM only downloads a POM file with a version mapping. You must still declare each dependency individually in your [module]/build.gradle.

Add the BOM to the dependencies block in your [module]/build.gradle.

dependencies {
    ...

    implementation platform('com.incode.sdk:bom:5.49.0')
}
dependencies {
    ...

    implementation(platform("com.incode.sdk:bom:5.49.0"))
}

Declare Dependencies

Add the following to your [module]/build.gradle. welcome and core-light are required. All others are optional; add them only if your integration uses the features they provide. If you added the Incode BOM, omit version numbers.

dependencies {
    ...

    // Incode Omni SDK
    implementation 'com.incode.sdk:welcome' // Required core dependency
    implementation 'com.incode.sdk:core-light' // Required core dependency

    // The following dependencies are optional and needed only in very specific use cases.
    // Make sure you are using the features they provide before adding the dependencies below.
    implementation 'com.incode.sdk:extensions' // Optional dependency
    implementation 'com.incode.sdk:nfc' // Optional dependency
    implementation 'com.incode.sdk:video-streaming' // Optional dependency

    implementation 'com.incode.sdk:model-face-recognition' // Optional dependency
    implementation 'com.incode.sdk:model-liveness-detection' // Optional dependency
    implementation 'com.incode.sdk:model-face-occlusion' // Optional dependency
    implementation 'com.incode.sdk:model-age-estimation' // Optional dependency
    implementation("com.incode.sdk:wallets") // Optional dependency
}
dependencies {
    ...

    // Incode Omni SDK
    implementation("com.incode.sdk:welcome") // Required core dependency
    implementation("com.incode.sdk:core-light") // Required core dependency

    // The following dependencies are optional and needed only in very specific use cases.
    // Make sure you are using the features they provide before adding the dependencies below.
    implementation("com.incode.sdk:extensions") // Optional dependency
    implementation("com.incode.sdk:nfc") // Optional dependency
    implementation("com.incode.sdk:video-streaming") // Optional dependency

    implementation("com.incode.sdk:model-face-recognition") // Optional dependency
    implementation("com.incode.sdk:model-id-face-detection") // Optional dependency
    implementation("com.incode.sdk:model-liveness-detection") // Optional dependency
    implementation("com.incode.sdk:model-face-occlusion") // Optional dependency
    implementation("com.incode.sdk:model-age-estimation") // Optional dependency
    implementation("com.incode.sdk:wallets") // Optional dependency
}
Dependency Type Description
welcome Required Core dependency; contains all core SDK functionality and the IncodeWelcome entry point.
core-light Required Contains image-processing libraries used throughout the SDK.
extensions Optional Required for custom theme configuration, dynamic localization, and runtime localization. See Customization.
nfc Optional Required for the NFC Scan module. See NFC Scan for additional configuration.
video-streaming Optional Required by the Conference module and the streamFrames feature in the ID Scan and Selfie Scan modules.
model-face-recognition Optional Required for on-device face recognition. Used by face login in the Selfie Scan module​ only.
model-liveness-detection Optional Required for on-device liveness detection in the Selfie Scan module via SelfieScan.Builder().setFaceAuthMode(SelfieScan.FaceAuthMode.LOCAL).
model-face-occlusion Optional Required for on-device face occlusion detection in the Selfie Scan module via SelfieScan.Builder().setFaceOcclusionEnabled(true).
model-age-estimation Optional Required for on-device age estimation in the Selfie Scan module via SelfieScan.Builder().setOnDeviceFaceResultsSubmissionEnabled(true).
wallets Optional Required for wallet integrations, including Google Wallet ID.

After adding dependencies, build the project. Troubleshoot if you encounter errors. For the version mapped to each dependency, see BOM Version Mapping.

Override a Dependency Version

Overriding a BOM dependency version is not recommended. If necessary, specify the version where it would normally be omitted.

dependencies {
    ...

    implementation platform('com.incode.sdk:bom:5.49.0')

    // Required core dependencies
    implementation 'com.incode.sdk:welcome'
    implementation 'com.incode.sdk:core-light'

    // Optional dependencies
    implementation('com.incode.sdk:video-streaming') {
        version {
            strictly 'x.x.x-1'
        }
    }
}
dependencies {
    ...

    implementation(platform("com.incode.sdk:bom:5.49.0"))

    // Required core dependencies
    implementation("com.incode.sdk:welcome")
    implementation("com.incode.sdk:core-light")

    // Optional dependencies
    implementation("com.incode.sdk:video-streaming") {
        version {
            strictly("x.x.x-1")
        }
    }
}

Declare Required Permissions

The SDK declares the following permissions in its manifest files:

  • com.incode.sdk:welcome
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    
  • com.incode.sdk:nfc
    <uses-permission android:name="android.permission.NFC" />
    

If your app does not use the screen recording features of the ID Scan, Selfie Scan, or Video Selfie modules, you can omit the foreground service permissions. Add the following to your AndroidManifest.xml:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" tools:node="remove" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" tools:node="remove" />

If the manifest fails to merge during a build, troubleshoot.

Info

Camera Lint Warning

The SDK manifest declares <uses-feature android:name="android.hardware.camera" />, so the merged manifest already advertises the camera requirement. If Android Lint flags PermissionImpliesUnsupportedHardware on your own module, declare the feature explicitly in your AndroidManifest.xml:

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

Use android:required="false" only if you want your app installable on devices without a camera. The SDK's capture flows require one.


Add Optional Permissions

Some SDK features work better with additional permissions. These permissions may subject your app to additional scrutiny when publishing on Google Play. Declare them only if your app has an existing use case for them.

Query All Apps on Android 11+

On Android 11 and later, root detection skips additional actions. This can result in some rooted devices going undetected. Add the following permission to enable the SDK's root detection to take more actions and find evidence of a rooted device.

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

On earlier Android versions, actions that require QUERY_ALL_PACKAGES are taken by default.

Enable Higher Sampling Rates on Android 12+

On Android 12 and later, the second highest sample rate is used by default when determining the device's motionStatus for the ID Scan and Selfie Scan modules. Add the following permission to maximize the sampling rate used.

<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />

On earlier Android versions, the highest sampling rate is used automatically.


Initialize the SDK

Add the following to the class that extends Application:

override fun onCreate() {
    super.onCreate()
    ...
    IncodeWelcome.Builder(this, WELCOME_API_URL, WELCOME_API_KEY)
        .setSSLConfig(sslConfig) // optional SSL config for on-premise servers
        .setLoggingEnabled(loggingEnabled) // enable/disable logcat logs. These are enabled by default
        .build()
    ...
}
@Override
public void onCreate() {
    super.onCreate();
    ...
    new IncodeWelcome.Builder(this, WELCOME_API_URL, WELCOME_API_KEY)
            .setSSLConfig(sslConfig) // optional SSL config for on-premise servers
            .setLoggingEnabled(loggingEnabled) // enable/disable logcat logs. These are enabled by default
            .build();
    ...
}
  • WELCOME_API_URL and WELCOME_API_KEY are provided by Incode.
  • build() creates the IncodeWelcome singleton. You can only make SDK API calls after initialization.
  • setSSLConfig() is optional. Use it to specify SSL config for your own on-prem servers.
  • setLoggingEnabled() is optional. Use it to enable or turn off logcat logs. Logs are enabled by default.

See API Reference for the complete specification of the IncodeWelcome.Builder and SSLConfig.

Initialize from an Activity

Incode recommends initializing the SDK in your Application class's onCreate() method, as shown above. If you initialize within an Activity instead, guard the call with isInitialized() inside onCreate():

override fun onCreate() {
    super.onCreate()
    ...
    if (!IncodeWelcome.isInitialized()) {
        IncodeWelcome.Builder(this, WELCOME_API_URL, WELCOME_API_KEY)
            .setSSLConfig(sslConfig) // optional SSL config for on-premise servers
            .setLoggingEnabled(loggingEnabled) // enable/disable logcat logs. These are enabled by default
            .build()
    }
    ...
}
@Override
public void onCreate() {
    super.onCreate();
    ...
    if (!IncodeWelcome.isInitialized()) {
        new IncodeWelcome.Builder(this,WELCOME_API_URL,WELCOME_API_KEY)
        .setSSLConfig(sslConfig) // optional SSL config for on-premise servers
        .setLoggingEnabled(loggingEnabled) // enable/disable logcat logs. These are enabled by default
        .build();
    }
    ...
}

Initialize with an External Token

You can initialize the SDK with an external token instead of an API key.

  1. Initialize the SDK with IncodeWelcome.Builder($CONTEXT, $WELCOME_API_URL):
    IncodeWelcome.Builder($CONTEXT, $WELCOME_API_URL)
            // additional config
            .build()
    
    new IncodeWelcome.Builder($CONTEXT, $WELCOME_API_URL)
            // additional config
            .build();
    
  2. Create a SessionConfig object with the external token:
    val sessionConfig = SessionConfig.Builder()
            .setExternalToken($EXTERNAL_TOKEN) // add external token here
            .build()
    
    SessionConfig sessionConfig = new SessionConfig.Builder()
            .setExternalToken($EXTERNAL_TOKEN) // add external token here
            .build();
    

Enable Test Mode

Test Mode lets you run and test the SDK on an emulator during development. Add setTestModeEnabled(true) to the IncodeWelcome.Builder chain in your Application class.

IncodeWelcome.Builder(this, WELCOME_API_URL, WELCOME_API_KEY)
    .setTestModeEnabled(true) // enable Test Mode for emulator testing
    .build()
new IncodeWelcome.Builder(this, WELCOME_API_URL, WELCOME_API_KEY)
    .setTestModeEnabled(true) // enable Test Mode for emulator testing
    .build();

With Test Mode enabled, camera-dependent modules skip capture on an emulator. Instead, they show a placeholder screen and finish automatically with an emulator-detected result code:

  • Document Scan, Face Match, Selfie Scan, and Video Selfie: ResultCode.EMULATOR_DETECTED as resultCode.
  • ID Scan: IdResults.RESULT_EMULATOR_DETECTED as frontIdResult and backIdResult.

Danger

Warning

Remove setTestModeEnabled(true) before you build for production. Test Mode is for development only.


What's Next

After the project successfully builds, you can begin integration​.


Was this page helpful?