Skip to main content
Native Android capture for rial — the SDK takes the photo, signs it with device signals (hardware attestation, location) and submits it for verification.

Requirements

Install

Access. Published to GitHub Packages. The repository is private — you’ll need a PAT with read:packages scope from a GitHub account that has access to rial-kotlin. Ask your rial contact for access.
settings.gradle
Set gpr.user and gpr.token in ~/.gradle/gradle.properties — never commit them.Public distribution via Maven Central is planned — this step disappears then.
Permissions (CAMERA, INTERNET, location) are contributed by the SDK’s own manifest via the manifest merger — there’s nothing to declare yourself. Each module also ships its own R8 consumer rules, so integrating the SDK doesn’t require writing any ProGuard/R8 rules of your own.

Configure once

Call this from your Application.onCreate:

Template flow (turnkey)

The org and template slugs come from the template link published in the dashboard (/l/{org}/{template}):
This renders the complete flow: typed steps, the tenant’s branding, camera, review, and a durable submit backed by WorkManager — offline retries, and it resumes after the process is killed. Rotations are survived by reusing the same verification instead of starting over. For finer control, combine Rial.openFlow(...) with RialTemplateFlow(outcome.session, activity).

Camera only (bring your own UI)

Offline & durability

The SDK is built to survive a flaky connection and a killed process, not just a happy path. Template flow. Once a photo is captured, submitting it is a durable job: the complete submission intent (token, snapshots, answers) is persisted to disk before WorkManager takes ownership of it — so a job that’s merely serialized but never scheduled doesn’t count as saved. A transient failure (a 5xx, no network) returns WorkManager’s retry and keeps the job; the app can be killed and reopened mid-upload and the submission resumes where it left off. Only a terminal outcome — success, or a non-retryable rejection — clears the durable job and its JPEG together. Camera-only path. If the device is offline at capture time, RialClient.capture(...) hands the work to the same offline queue instead of failing: see RialResult below.

Error handling

RialResult — returned by RialClient.capture(...):
Usually captureId is the server-assigned id. If the device was offline at capture time, the upload was handed to the offline queue instead: queued is true, captureId is null (the server assigns one once the queued upload completes), and queueId is the WorkManager work id — observe it (e.g. WorkManager.getWorkInfoByIdFlow) to drive a UI badge from “pending” to “uploaded.” FlowOutcome — returned by Rial.openFlow(...) / RialFlowClient.open(...) when opening a template link:
NotFound covers a link that’s missing, still a draft, paused, or out of capacity — the server doesn’t distinguish these to the outside on purpose, so the SDK doesn’t invent a distinction either. Expired is a verification past its expires_at. AlreadyUsed means it’s already completed — nothing left to capture. Transport is a network failure or a response the SDK couldn’t parse.

Testing against staging

Modules

Dependencies run in one direction: ui → flow → core.

Next steps

Authentication

Environments, and how publishableKey fits alongside the secret key.

Verdicts

What the verification you just captured against will come back with.