# Android Quick Start

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

:::note

Work through [Prerequisites](/docs/v2.0/getting-started/prerequisites/) first. You will need a registered app (or a sandbox token for local development) and a plan for runtime permissions.

:::

---

## 1. Add the Maven repo

In your project's root `settings.gradle.kts`:

```kotlin
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`:

```kotlin
dependencies {
    implementation("com.octetproof:sdk:2.0.0")
}
```

Pin 2.0.0 or later. 2.0 is a major release. If you are on 1.x, read [Migrating from 1.x](/docs/v2.0/getting-started/migrating-from-1x/) first.

Sync Gradle. The SDK's foreground permissions merge into your manifest automatically. For proofs while the app is backgrounded, add `ACCESS_BACKGROUND_LOCATION` to your own manifest. See [Prerequisites](/docs/v2.0/getting-started/prerequisites/).

---

## 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(...)`:

```kotlin
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

`Octet.start(...)` bootstraps the license by attesting the app with Android hardware key attestation, then brings up the proof pipeline. On a real device, no key or token is needed (see [Prerequisites](/docs/v2.0/getting-started/prerequisites/)).

```kotlin
import com.octetproof.sdk.api.Octet
import com.octetproof.sdk.api.OctetConfig

lifecycleScope.launch {
    val config = OctetConfig(licenseKey = "")   // required by the type, ignored by start
    val sdk = Octet.start(context = applicationContext, config = config)
    // sdk is ready
}
```

On an **emulator** or a locally built debug build, there is no hardware attestation. Mint a sandbox bypass token (see [Prerequisites](/docs/v2.0/getting-started/prerequisites/)) and pass it:

```kotlin
val config = OctetConfig(licenseKey = "", sandboxBypassToken = "octet_sbx_...")
```

`Octet.start(...)` is a `suspend` function. Any license or bootstrap problem throws a typed `LicenseError`. See [License Types](/docs/v2.0/api-reference/license-types/) and [Attested bootstrap](/docs/v2.0/concepts/attested-bootstrap/).

---

## 5. Ask your first question

```kotlin
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`](/docs/v2.0/api-reference/octet-verdict/). Never treat `INDETERMINATE` as `NO`.

---

## 6. Close when done

When your proof flow ends, release the session and stop the location foreground service:

```kotlin
sdk.close()
```

See [Session Lifecycle](/docs/v2.0/concepts/lifecycle/) for why this matters.

---

## 7. 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. Run on hardware to see the full flow.
- **On a real device, indoors**, a `country` query can often answer. See [Concepts: Verdicts](/docs/v2.0/concepts/verdicts/).

---

## 8. From here

- The [Android sample app](/docs/v2.0/samples/android-toy-app/) exercises this whole flow.
- [On-device Verification](/docs/v2.0/concepts/on-device-verification/) checks a proof with [`Octet.verify`](/docs/v2.0/api-reference/octet-verify/), offline.
- [Proof Binding](/docs/v2.0/concepts/proof-binding/) ties a proof to a login or a decision, and `forceFresh` mints one on demand.
- [Verifying Proofs](/docs/v2.0/concepts/verifying-proofs/) and the [Verifier Quick Start](/docs/v2.0/getting-started/verifier-quickstart/) show independent verification.
- [What's new in 2.0](/docs/v2.0/whats-new/) lists the full release.
