Android
The following guide will get you started with the Android SDK for Incode Onboarding.
Minimum hardware requirements
Ram: 3GB
Back-facing camera: 5MP
Front-facing (selfie) camera: 2MP
Installation
The Incode Android SDK is distributed through Maven. To receive credentials for the SDK, please reach out to your enterprise customer success manager or contact [email protected].
Add the following maven repository to your project dependencies. Read the Gradle documentation about declaring dependencies for more information.
repositories {
maven {
url "https://repo.incode.com/artifactory/libs-incode-welcome"
credentials {
username = "organizationUsername"
password = "xxxxxxxxxxxxxxxxxxxx"
}
}
}
The Incode SDK is dependent on jitpack, so the following maven repository needs to be added as well.
repositories {
maven { url "https://jitpack.io" }
}
Finally, don't forget to add Google and Maven Central to the file if it's not there already.
repositories {
google()
mavenCentral()
}
The dependencies should look like the following.
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
maven {
url "https://repo.incode.com/artifactory/libs-incode-welcome"
credentials {
username = "organizationUser"
password = "password"
}
}
}
In your module-level app/build.gradle
, we require a minimum of Java 8 for both source
and targetCompatibility
. To enforce this, add the following code inside your android{}
block:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Next, in your app/build.gradle, add Incode library dependencies as described below.
Dependencies
Core dependencies must be included. Optional ones should be added as needed, based on the use case - see below.
dependencies {
...
// Incode Welcome SDK
implementation 'com.incode.sdk:welcome:5.31.0' // Incode Welcome SDK
implementation 'com.incode.sdk:core-light:2.6.5' // Required core dependency
implementation 'com.incode.sdk:camera:1.0.1' // Required core dependency if ID capture V2 experience should be used
// 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:1.1.0' // Optional dependency
implementation 'com.incode.sdk:kiosk-login:1.3.5' // Optional dependency
implementation 'com.incode.sdk:nfc:1.3.5' // Optional dependency
implementation 'com.incode.sdk:qr-face-login:1.2.3' // Optional dependency
implementation 'com.incode.sdk:video-streaming:1.5.5' // Optional dependency
implementation 'com.incode.sdk:model-face-recognition:3.2.0' // Optional dependency
implementation 'com.incode.sdk:model-id-face-detection:2.1.0' // Optional dependency
implementation 'com.incode.sdk:model-liveness-detection:3.2.0' // Optional dependency
}
-
The
core-light
dependency is required as it contains the image processing libraries used in the Welcome SDK. -
The
extensions
dependency is optional and is necessary only for using Dynamic Localization or a custom Theme Configuration. -
The
kiosk-login
dependency is optional and is needed if you are using theKiosk Login
feature of the SDK. It also requires additional configuration, as described here. -
The
nfc
dependency is optional and is required if you are using theNFC Scanning
feature of the SDK. Additional configuration is also required, as described here. -
The
qr-face-login
dependency is optional and is necessary if you are using theQR Face Login
feature of the SDK. It also requires additional repositories configuration, as described here. -
The
video-streaming
dependency is optional and is needed if you are using theConference
module or thestreamFrames
feature in theIdScan
andSelfieScan
modules. -
The
model-face-recognition
dependency is optional and is required if you are using the face recognition feature that runs locally on the device. This feature is only available for Face Login. -
The
model-id-face-detection
dependency is optional and is necessary if you are using checks to detect the front/back side of an ID. -
The
model-liveness-detection
dependency is optional and is required if you are using the liveness detection feature that runs locally on the device.
Finally, try building the project after all of the dependencies are added. If you encounter issues during the build process, refer to the troubleshooting section.
Once the project successfully builds. It is time to start integration.
Troubleshooting
Attribute application@allowBackup value=(true) from AndroidManifest.xml
Attribute application@allowBackup value=(true) from AndroidManifest.xml is also present at [com.incode.sdk:welcome:x.x.x] AndroidManifest.xml value=(false).
Suggestion: add 'tools:replace="android:allowBackup"' to `<application>` element at AndroidManifest.xml to override.
Solution
This means that you have set allowBackup
in your AndroidManifest.xml
to true
, but the Welcome SDK has this value set to false
.
Having allowBackup
set to true
is a potential security issue, so we suggest setting it to false
.
If you are sure that you wish to allow backups, then add tools:replace="android:allowBackup"
to <application>
element in your AndroidManifest.xml
.
If you already have some attributes in tools:replace
, separate them with commas (for example: "android:label,android:allowBackup").
Static interface methods are only supported starting with Android N
Static interface methods are only supported starting with Android N (--min-api 24): Lbutterknife/Unbinder;lambda$static$0()V
Error while dexing. The dependency contains Java 8 bytecode. Please enable desugaring by adding the following to build.gradle
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}}
Solution
In your module-level [module]/build.gradle
, add the following code to android{}
closure:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
All modules with native libraries must support the same set of ABIs
Execution failed for task ':app:packageDebugBundle'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
> All modules with native libraries must support the same set of ABIs, but module 'base' supports '[X86, ARMEABI_V7A, ARM64_V8A, X86_64, MIPS, ARMEABI]' and module 'incode_core' supports '[ARMEABI_V7A, X86, X86_64, ARM64_V8A]'.
- problem when generating bundles.
Solution
Add the following ndk abi filters to your module-level app/build.gradle
inside defaultConfig{}
closure:
ndk {
abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"
}
FATAL EXCEPTION: RxCachedThreadScheduler
E/AndroidRuntime: FATAL EXCEPTION: RxCachedThreadScheduler-2
Process: com.incode.welcome.example, PID: 6842
io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.lang.NoSuchMethodError: No virtual method log(ILjava/lang/String;Ljava/lang/Throwable;)V in class Lokhttp3/internal/platform/Platform; or its super classes (declaration of 'okhttp3.internal.platform.Platform' appears in /data/app/com.incode.welcome.example-HnCVs4pdPTZBq3BhFsJmdQ==/base.apk!classes3.dex)
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:69)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.NoSuchMethodError: No virtual method log(ILjava/lang/String;Ljava/lang/Throwable;)V in class Lokhttp3/internal/platform/Platform; or its super classes (declaration of 'okhttp3.internal.platform.Platform' appears in /data/app/com.incode.welcome.example-HnCVs4pdPTZBq3BhFsJmdQ==/base.apk!classes3.dex)
at okhttp3.logging.HttpLoggingInterceptor$Logger$1.log(HttpLoggingInterceptor.java:114)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:173)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:148)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:186)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Solution
This crash occurs when the okhttp3:okhttp
dependency version is different from okhttp3:logging-interceptor
or okhttp3:okhttp-urlconnection
dependencies and trying to init Incode SDKs.
For example, in case you have in the Project's External Libraries
the following dependencies, you will face the crash because of the version inconsistency:
okhttp3:logging-interceptor:3.4.1
okhttp3:okhttp-urlconnection:3.4.1
okhttp3:okhttp:4.5.0
To fix the crash, for the example above, you need to bump the version of okhttp3:logging-interceptor
& okhttp3:okhttp-urlconnection
to 4.5.0
.
Add the following implementations inside build.gradle
to override existing lower versions:
dependencies {
...
implementation 'com.squareup.okhttp3:logging-interceptor:4.5.0'
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.5.0'
}
It is important to note that the crash will still occur in the case you only have the logging-interceptor
or okhttp-urlconnection
dependency.
Crashes if you have in External Libraries
these dependencies:
okhttp3:logging-interceptor:3.4.1
okhttp3:okhttp:4.5.0
Crashes as well if you have in External Libraries
these dependencies:
okhttp3:okhttp-urlconnection:3.4.1
okhttp3:okhttp:4.5.0
InvalidUserCodeException: Build was configured to prefer settings
org.gradle.api.InvalidUserCodeException: Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by build file 'build.gradle'
Solution
For projects using Gradle 6.8 or higher, a new way of defining dependencies in settings.gradle
with the dependencyResolutionManagement
block was introduced. Moving the maven
repo declaration from the project build.gradle
to here should resolve it. See also StackOverflow.
dependencyResolutionManagement {
...
repositories {
...
maven {
url "https://repo.incode.com/artifactory/libs-incode-welcome"
credentials {
username = "organizationUsername"
password = "xxxxxxxxxxxxxxxxxxxx"
}
}
}
}
A problem occurred evaluating root project
Build was configured to prefer settings repositories over project repositories but repository 'Google' was added by build file 'build.gradle'
Solution
In the settings.gradle file, ensure that the repositoriesMode is set to RepositoriesMode.PREFER_PROJECT
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
repositories {
google()
mavenCentral()
}
}
Fatal error during SentryAndroid.init(...)
Since version 5.24.0, the Incode SDK includes the Sentry SDK for crash reporting.
We are currently using version 7.x.x, and if your project happens to be using a different major version (such as 6.x.x),
the following crash can occur:
java.lang.RuntimeException: Unable to get provider io.sentry.android.core.SentryInitProvider: java.lang.RuntimeException: Failed to initialize Sentry's SDK
...
Caused by: java.lang.RuntimeException: Failed to initialize Sentry's SDK
...
Caused by: java.lang.reflect.InvocationTargetException
...
Caused by: java.lang.NoSuchMethodError: No virtual method setEnableScopeSync(Z)V...
If you are affected by this error, you will need to upgrade to version 5.25.0 or newer, and apply the following workaround:
- Exclude the Sentry library from Incode SDK:
implementation ('com.incode.sdk:welcome:5.25.0') { // Mandatory dependency
exclude group: 'io.sentry', module: 'sentry'
}
- Disable Incode SDK's crash reporting:
new IncodeWelcome.Builder()
...
.setCrashReportingEnabled(false)
.build();
IncodeWelcome.Builder()
...
.setCrashReportingEnabled(false)
.build()
Updated 10 days ago
Next, check out the Standard Integration guide on getting Incode up and running.