Android quickstart
Get face liveness detection running in your Android app in under five minutes.
Get face liveness detection running in your Android app in under five minutes.
What you'll build
A single button that launches the iLive liveness verification flow —
camera preview, face detection, on-device analysis — and returns a
verdict (PASS / FAIL / RETRY) with confidence scores.
Requirements
| Requirement | Minimum |
|---|---|
| Android Studio | Hedgehog 2023.1.1+ |
| JDK | 17 |
| Min SDK | 26 (Android 8.0) |
| Target / Compile SDK | 35 |
| Kotlin | 2.1.0 |
Step 1: Add dependencies
Add the iLive SDK modules to your project. For local development, include the modules directly:
settings.gradle.kts:
app/build.gradle.kts:
Also ensure you have the shared version catalog. Copy
ilive-android-sdk/gradle/libs.versions.toml to your project's gradle/
directory, or add the iLive entries to your existing catalog.
Step 2: Add camera permission
AndroidManifest.xml:
No runtime permission handling needed — the SDK handles it internally.
Step 3: Add the SDK model assets
The SDK ships with a set of model files it loads at runtime. Copy them
into ilive-core/src/main/assets/models/ following the instructions in
the SDK distribution bundle. The SDK's README lists the exact files and
expected sizes.
The models are distributed separately from the SDK source to keep the
git repository small. Your SDK bundle includes a models/ directory —
copy its contents into ilive-core/src/main/assets/models/ before your
first build.
Step 4: Launch the liveness flow
The SDK ships two entry points — a drop-in activity for the fastest integration, and a lower-level engine if you want to build your own UI.
Launch the pre-built LivenessActivity with LivenessContract — a
type-safe ActivityResultContract that returns a sealed LivenessOutcome:
The legacy launch path that reads LivenessActivity.pendingResult after
StartActivityForResult is deprecated and will be removed in a
future release. Prefer LivenessContract.
Step 5: Handle the result
Configuration
Passive mode vs challenge mode
| Mode | How it works | When to use |
|---|---|---|
Passive (passiveMode = true) | Camera captures frames silently for about 3 seconds, then runs anti-spoof, deepfake, face-consistency, and motion analysis. No user interaction needed. | Low-friction onboarding, background verification |
Challenge (passiveMode = false) | User completes 3–6 randomized challenges (blink, turn head, smile, etc.), then analysis runs on the captured frames. The challenge score is an additional verification layer. | High-security scenarios, regulatory compliance |
Both modes use the same underlying analysis pipeline. Passive mode redistributes the challenge weight across the other four layers.
LivenessResult fields
| Field | Type | Description |
|---|---|---|
sessionId | String | Unique session identifier (UUID) |
verdict | Verdict | PASS, FAIL, or RETRY |
confidence | Float | Weighted aggregate score (0.0–1.0) |
layerScores | List<LayerScore> | Per-layer breakdown (anti-spoof, deepfake, consistency, motion) |
retryHint | String? | User-facing suggestion on RETRY |
failureReason | String? | Internal reason on FAIL |
icaoPhoto | ByteArray? | JPEG passport photo (480×600) on PASS |
photoQualityScore | Float? | Photo quality (0.0–1.0) |
attestation | Attestation? | Signed payload (if key configured) |
encryptedFrameBundle | FrameBundle? | Encrypted frames (if key configured) |
metadata | SessionMetadata | Duration, device, SDK version |
Face comparison
Compare the verified face against a reference photo (for example, an ID document):
For faster repeat comparisons, store the face embedding from the liveness result:
| Parameter | Default | Description |
|---|---|---|
threshold | 0.45 | Minimum similarity for a match (0.0–1.0) |
Troubleshooting
App crashes on launch: Ensure the SDK model files are in
assets/models/ — the SDK README lists the full file inventory.
Face not detected: Camera frames are rotated to portrait orientation automatically. Ensure the phone is held upright.
All scores show around 50%: The analyzers may be failing silently. Check logcat for SDK errors — usually a missing model file or an asset path mismatch.
"Move closer" even when close: The face must occupy at least 2% of the frame area. At arm's length this is typically met.
Build error "Duplicate class org.tensorflow.lite": Add the following
to your app's build.gradle.kts: