Android Quick Start
From zero to a YES verdict on an Android device in ten minutes.
Work through Prerequisites first. You will need a license key and a plan for runtime permissions.
1. Add the Maven repo
In your project's root settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven {
url = uri("https://raw.githubusercontent.com/octetproof/octet-sdk-android/mvn-repo")
}
}
}
The OctetSDK Maven artifacts live on the mvn-repo orphan branch of the public octet-sdk-android repository.
2. Add the dependency
In your app build.gradle.kts:
dependencies {
implementation("com.octetproof:sdk:1.2.1")
}
Pin 1.2.1 or later. Versions 1.0.0, 1.1.0, and 1.2.0 are deprecated for security reasons, and their artifacts have been removed from the Maven repo, so a build pinned to one of them no longer resolves.
Sync Gradle. The SDK's foreground permissions merge into your manifest automatically, so you declare none of them yourself. For proofs while the app is backgrounded, add ACCESS_BACKGROUND_LOCATION to your own manifest. See Prerequisites.
Verify the download (optional)
Each release publishes a SHA-256 checksum, SLSA build provenance, an SBOM (software bill of materials), and a keyless cosign signature for the AAR. To check them in a release pipeline, follow the "Verifying the download" section of INTEGRATION.md. A build runs without this step.
3. Request runtime permissions
The SDK refuses to start without ACCESS_FINE_LOCATION. Motion-classification confidence degrades without ACTIVITY_RECOGNITION. Request both before calling Octet.start(...):
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACTIVITY_RECOGNITION,
),
REQUEST_CODE
)
Wait for onRequestPermissionsResult(...) to confirm ACCESS_FINE_LOCATION was granted before continuing.
4. Start the SDK
licenseKey is a placeholder. Get a free key (free for up to 1,000 proofs a month, no credit card) at sdk.octetproof.com/signup, then paste it in.
import com.octetproof.sdk.api.Octet
import com.octetproof.sdk.api.OctetConfig
lifecycleScope.launch {
val sdk = Octet.start(
context = applicationContext,
config = OctetConfig(licenseKey = "octet_live_v4.public.…")
)
// sdk is ready
}
Octet.start(...) is a suspend function. Call it from a coroutine scope (lifecycleScope, viewModelScope, or your own). On first launch the SDK verifies the license key locally, exchanges it for an activation token via api.octetproof.com/v1/activate, caches the token in EncryptedSharedPreferences, and brings up the proof pipeline.
Any license problem throws a typed LicenseError. See License Types.
5. Ask your first question
import com.octetproof.sdk.api.OctetRegion
import com.octetproof.sdk.api.OctetVerdict
import java.time.Instant
val verdict = sdk.loc.isWithin(
region = OctetRegion.country("US"),
atTime = Instant.now()
)
when (verdict.result) {
OctetVerdict.Result.YES ->
println("YES, proof attached: ${verdict.proof != null}")
OctetVerdict.Result.NO ->
println("NO, provable negative")
OctetVerdict.Result.INDETERMINATE ->
println("INDETERMINATE, reason: ${verdict.reason}")
}
The predicate returns an OctetVerdict. Never treat INDETERMINATE as NO.
6. What to expect
- On a real device, outdoors, with cellular and GPS available,
isWithin(country("US"))typically returnsYESwith an attached proof. - On the Android emulator the verdict will always be
INDETERMINATE / NO_FIXwith the messagerunning on emulator — location proofs are unavailable in this environment. This is by design. The emulator's mock-location flag blocks proof generation. Run on hardware to see the full flow. - On a real device, indoors, the first proof on Android usually arrives quickly via the cell-tower MCC signal even without GPS.
isWithin(country(...))typically succeeds withHIGHconfidence indoors on Android. Finer-grained predicates (city, polygon) may need a GPS fix. See Concepts: Verdicts.
7. From here
- The Android sample app is a single-button activity that exercises this whole flow.
- Concepts: Proof of Location explains what a verdict proves.
- Session-binding ties a proof to a specific login, so your verifier can confirm the proof was made for that login.
- Verifying Proofs and the Verifier Quick Start show how anyone can independently check the proofs your app produces.
- What's new in 1.2 lists the API added since 1.1.
- API Reference Overview maps the public surface.