Docs/Getting Started/Android Quick Start

Android Quick Start

From zero to a YES verdict on an Android device in ten minutes.

Note

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

Don't have a key yet?

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 returns YES with an attached proof.
  • On the Android emulator the verdict will always be INDETERMINATE / NO_FIX with the message running 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 with HIGH confidence indoors on Android. Finer-grained predicates (city, polygon) may need a GPS fix. See Concepts: Verdicts.

7. From here