A touchless fingerprint biometric capture SDK for Android that uses AI-powered hand detection to capture and process fingerprint images.
The RMS Techknowledgy Biometrics SDK brings touchless fingerprint verification to Android applications. Using only the device camera and AI-powered hand detection, it captures and verifies fingerprints without any dedicated scanning hardware. The SDK presents its own capture interface, guides the user through the scan, and returns a single result to your application — camera handling, permission prompts, and image processing are managed entirely by the SDK.
The SDK is written in Kotlin and can be used from both Kotlin and Java. Code samples for both languages are provided below.
| Requirement | Detail |
|---|---|
| Android SDK | minSdk 24, compileSdk 33 or higher |
| Kotlin Gradle plugin | 1.7.10 or newer |
| Camera | Device with a rear camera |
| Network | Active internet connection |
| Authentication token | Issued for your RMS Techknowledgy account |
Note: If your project already uses Kotlin, keep your existing version; there is no need to downgrade. Java-only projects must still apply the Kotlin plugin to the app module, although application code may remain entirely in Java.
A typical app module configuration:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 33
defaultConfig {
minSdk 24
targetSdk 33
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions { jvmTarget = '1.8' }
}Ensure that jvmTarget and the compileOptions Java version match; recent Gradle versions treat a mismatch as a build error.
For projects that do not use the plugins {} DSL, add the Kotlin classpath to the root build.gradle instead:
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
}
}The SDK is distributed exclusively through JitPack. The repository is private, so the access token provided with your license is required.
Add the JitPack repository to your project's settings.gradle:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url 'https://jitpack.io'
credentials { username authToken }
}
}
}Note: Define authToken in your gradle.properties using the access token provided with your license, rather than committing the token to source control.
Declare the dependency in your app module:
dependencies {
implementation 'com.github.RMS-Techknowledgy-Private-Limited:biometrics-sdk:1.0.6'
}After a Gradle sync, the integration is complete. All of the SDK's transitive dependencies are resolved automatically.
Older projects: For older projects — including most React Native templates — repositories may be declared in the root build.gradle under allprojects rather than in settings.gradle. In that case, place the JitPack block there. Declare the repository in one location only.
No permission configuration is required. The SDK's manifest declares the camera and internet permissions it needs, and Android merges them into your application at build time. The runtime camera prompt is also presented by the SDK on its own screen, so your application does not need to request it beforehand.
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.biometrics.Biometrics
import com.biometrics.model.BiometricsResult
class MainActivity : AppCompatActivity() {
// Register once, as a field or in onCreate. Registration must occur before
// the activity is started, so it cannot be placed inside a click listener.
private val biometrics = Biometrics.register(this) { result ->
handleResult(result)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<android.widget.Button>(R.id.verifyButton).setOnClickListener {
biometrics.launch(
token = "YOUR_AUTH_TOKEN",
nicNumber = "3520212345671"
)
}
}
private fun handleResult(result: BiometricsResult) {
when (result) {
is BiometricsResult.Success -> {
// The flow completed and a verdict was returned. Always check
// `outcome` — Success alone does not indicate a match.
when (result.outcome) {
"success" -> { /* verified — proceed */ }
"no-match" -> { /* fingerprints did not match */ }
"error" -> { /* processing problem — offer a retry */ }
}
// Store result.trnxId with your records. It is the reference
// for any support or billing queries.
result.fingers.forEach { f ->
Log.d("Biometrics", "${f.finger}: ${f.matchResult} (${f.matchScore})")
}
}
is BiometricsResult.Error -> {
Log.e("Biometrics", result.message)
}
is BiometricsResult.Cancelled -> {
// The user closed the flow. No transaction was created.
}
}
}
}Registration from a Fragment works identically: Biometrics.register(fragment) { ... }.
The user selects which hand to scan within the SDK itself, so no parameters beyond the token and NIC number are required.
Biometrics.register(activityOrFragment) { result -> } registers the result callback and returns a BiometricsLauncher. Call it once per Activity or Fragment, early in the lifecycle — a field initializer or onCreate are both appropriate.
BiometricsLauncher.launch(token, nicNumber) starts the verification flow.
token — the authentication token obtained from your backend. An invalid or expired token produces an Error result.nicNumber — the NIC/CNIC number against which the fingerprints are verified.BiometricsResult is delivered exactly once per launch, on the main thread, as one of three types:
Success — the flow completed and a verdict was returned. It carries:trnxId — the transaction identifier. Store it; it is the reference for any follow-up enquiry.outcome — "success", "no-match", or "error". This field holds the actual verdict.fingers — a list of FingerMatchResult entries, one per attempted finger, each containing finger, matchResult, an optional matchScore, and an optional matchMessage.Error(message) — the flow could not be completed (for example, an invalid token or a network failure). No transaction was created.Cancelled — the user exited the flow.Note: Success indicates only that the flow finished. The verification verdict is always in outcome.
launch may be called from any event — a button tap, a coroutine, or a React Native bridge method.onClick) raises LifecycleOwner is attempting to register while current state is RESUMED. Move the register call to a field initializer or to onCreate.register runs again in the re-created activity's onCreate — which it does when declared as a field — the result is delivered normally.BiometricsLauncher reference, and expose a bridge method that calls launch.| Issue | Solution |
|---|---|
Could not find com.github.RMS-Techknowledgy...:biometrics-sdk | The JitPack repository is missing from your configuration, or the authToken is absent or invalid |
Could not find method kotlinOptions() | The Kotlin Android plugin is not applied to your app module. See the Requirements section |
Inconsistent JVM-target compatibility (11 and 1.8) | The Kotlin jvmTarget and the Java compileOptions versions differ. Set both to the same value |
LifecycleOwner is attempting to register while current state is RESUMED | register was called too late in the lifecycle. Move it to a field initializer or to onCreate |
Error("Token or nicNumber is missing") | An empty token or NIC number was passed to launch |
| The camera opens but never captures | This usually indicates an invalid or expired token. Obtain a fresh token from your backend and try again. If the problem persists with a valid token, contact RMS Techknowledgy support |
Error("Processing error. Try again.") | The network request following the capture failed. Check connectivity and retry. If the issue recurs, note the time of occurrence and contact support |
| "Service configuration error" on the result screen | A server-side configuration issue. Contact RMS Techknowledgy support |
For tokens, licensing, or any matter not covered in this guide, contact your RMS Techknowledgy representative.
| Version | Notes |
|---|---|
| 1.0.6 | Latest stable release |
| 1.0.5 | Stable release. Fingerprint verification against a NIC number with outcome verdicts, transaction IDs, and Java support |
| 1.0.4 | Verification flow refinements and stability improvements |
| 1.0.3 | Initial release. Touchless fingerprint capture with PNG and WSQ output |