<!--
AppSprint docs markdown
Canonical HTML: https://appsprint.app/docs/android
Markdown URL: https://appsprint.app/docs/android.md
Docs index: https://appsprint.app/docs.md
Sitemap: https://appsprint.app/sitemap.xml
LLM guide: https://appsprint.app/llms.txt
-->

# Android (Kotlin)

Installation, configuration, event tracking, and full API reference for the Android (Kotlin) SDK.

## Requirements

- Android minSdk 21
- compileSdk 34+
- Java 17 (Kotlin 1.9+)

## 1. Install

Maven Central

```kotlin
// app/build.gradle.kts
dependencies {
    implementation("app.appsprint:sdk:1.0.2")
}
```

> Sync Gradle after adding the dependency. The SDK already declares INTERNET and com.google.android.gms.permission.AD_ID, so you do not need to add them to your manifest.

[View on Maven Central](https://central.sonatype.com/artifact/app.appsprint/sdk)

## 2. Configure

```kotlin
import com.appsprint.sdk.AppSprint
import com.appsprint.sdk.AppSprintConfig

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        AppSprint.shared(applicationContext).configure(
            AppSprintConfig(apiKey = "as_live_xxxxx")
        )
    }
}
```

Non-blocking. configure() returns immediately; install registration and device-info collection run off the main thread on the SDK's executor. The lifecycle observer is registered automatically.

### Configuration options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `String` | — | Your live API key (starts with as_live_). |
| `apiUrl` | `String` | https://api.appsprint.app | Override for staging or self-hosted environments. |
| `enableAppleAdsAttribution` | `Boolean` | false | iOS-only. Ignored on Android. |
| `customerUserId` | `String?` | null | Your internal user ID. Persists across launches and replays automatically if the first send fails. |
| `autoTrackSessions` | `Boolean` | true | Fires session_start on configure() and on ProcessLifecycleOwner.ON_START, debounced to one event per 30 minutes. |
| `autoRefreshAttribution` | `Boolean` | true | Refetches /v1/sdk/attribution on configure() and foreground transitions. |
| `googleAdsConsent` | `GoogleAdsConsent?` | null | Optional Google Ads ad user data consent forwarded as consent.adUserData on Google Ads uploads. |
| `isDebug` | `Boolean` | false | Forces logLevel = 0 (debug) and enables the optional debug overlay. |
| `logLevel` | `Int` | 2 (WARN) | 0 = DEBUG, 1 = INFO, 2 = WARN, 3 = ERROR. |

## 3. Track events

```kotlin
// Standard event
val appSprint = AppSprint.shared(applicationContext)
appSprint.sendEvent(AppSprintEventType.LOGIN)
```

```kotlin
// Revenue event. Currency must be a 3-letter ISO code.
appSprint.sendEvent(
    AppSprintEventType.PURCHASE,
    params = mapOf("revenue" to 9.99, "currency" to "USD")
)
```

```kotlin
// Custom event with parameters
appSprint.sendEvent(
    AppSprintEventType.CUSTOM,
    name = "level_complete",
    params = mapOf("level" to 5, "score" to 1200)
)
```

### Supported event types

`session_start`, `login`, `sign_up`, `register`, `purchase`, `subscribe`, `start_trial`, `add_payment_info`, `add_to_cart`, `add_to_wishlist`, `initiate_checkout`, `view_content`, `view_item`, `search`, `share`, `tutorial_complete`, `achieve_level`, `level_start`, `level_complete`, `custom`

## 4. Read attribution

```kotlin
val attr = appSprint.getAttribution()
println(attr?.source)         // "apple_ads", "tracking_link", or "organic"
println(attr?.isAttributed)   // Boolean
println(attr?.campaignName)   // Campaign name when available
println(attr?.link?.name)
```

## API reference

### `configure(config)`

Initializes the SDK. Returns immediately; install registration and lifecycle wiring run on the SDK executor.

```kotlin
appSprint.configure(AppSprintConfig(apiKey = "…"))
```

### `sendEvent(type, name?, params?)`

Enqueues an event locally and schedules a flush.

```kotlin
appSprint.sendEvent(AppSprintEventType.PURCHASE, params = mapOf("revenue" to 9.99, "currency" to "USD"))
```

### `flush()`

Drains the queue immediately.

```kotlin
appSprint.flush()
```

### `refreshAttribution()` → AttributionResult?

Fetches the latest attribution. Blocking; call from a background thread. Self-heals on 404 install_not_found.

```kotlin
val attr = appSprint.refreshAttribution()
```

### `setCustomerUserId(id)`

Updates the customer user ID. Persists to disk and retries on the next configure() or foreground if the first send fails.

```kotlin
appSprint.setCustomerUserId("user-123")
```

### `getAppSprintId()` → String?

Returns the install ID, or null before install registration completes.

```kotlin
val id = appSprint.getAppSprintId()
```

### `getAttribution()` → AttributionResult?

Returns the cached AttributionResult.

```kotlin
val attr = appSprint.getAttribution()
```

### `getAttributionParams()` → Map<String, String>

Partner-ready flat payload for forwarding to RevenueCat, Superwall, etc.

```kotlin
val params = appSprint.getAttributionParams()
```

### `enableAppleAdsAttribution()` → Boolean

Returns false on Android. Apple Ads attribution is iOS-only.

```kotlin
appSprint.enableAppleAdsAttribution()
```

### `isInitialized()` → Boolean

True after configure() returns.

```kotlin
appSprint.isInitialized()
```

### `isSdkDisabled()` → Boolean

True if a 401 or 403 permanently disabled the SDK.

```kotlin
appSprint.isSdkDisabled()
```

### `sendTestEvent()` → TestEventResult

Posts a diagnostic event off the main thread. From the main thread, use sendTestEventAsync(callback).

```kotlin
val result = appSprint.sendTestEvent()
```

### `clearData()`

Wipes local state and the event queue.

```kotlin
appSprint.clearData()
```


## Offline behavior

- Events that fail to send are automatically queued in native storage (up to 100 events).
- The queue persists across app restarts.
- Queued events are retried automatically when configure() completes, when the app moves to the background, or when you call flush().
- If a queued event receives a 401/403, the SDK disables itself and clears the queue.

## Platform notes

- configure() is thread-safe (@Synchronized) and returns immediately. Safe to call from Application.onCreate() or an activity.
- Apple Search Ads attribution is iOS-only. enableAppleAdsAttribution is accepted for cross-platform symmetry but does nothing on Android.
- GAID is read during install registration only, off the main thread. The SDK honors Limit Ad Tracking and drops the all-zero advertising ID so a bogus value never reaches the backend.
- Play Install Referrer is collected automatically. The package visibility entry for com.android.vending is in the SDK manifest, so it works on apps targeting Android 11+.
- If your app cannot collect advertising IDs (children's apps, regional policies), remove com.google.android.gms.permission.AD_ID in your host manifest with tools:node="remove".
- Events persist in SharedPreferences. They flush on foreground (ProcessLifecycleOwner.ON_START), background, the next sendEvent, or an explicit flush() call.

## Troubleshooting

**getAppSprintId() returns null**
configure() returns before install registration finishes. Check isInitialized() and retry briefly, or read the value inside an event handler that fires after first launch.

**Events do not appear in dashboard**
Confirm the API key starts with as_live_. Call sendTestEvent() and inspect the result. Lower logLevel to 0 and check logcat under the AppSprint tag.

**SDK disabled after 401/403**
A rejected key disables the SDK permanently. Call clearData(), then configure() with a valid key.

**Events lost after app kill**
Events persist to SharedPreferences and resend on the next configure(). If they still do not appear, the queue may have been dropped by clearData() or hit the 100-entry cap.

**AD_ID permission rejected by Play review**
Either include advertising ID collection in your Data safety answers, or remove the permission with tools:node="remove" in your host manifest.

## Connectivity test

```kotlin
val result = appSprint.sendTestEvent()
println("${result.success} — ${result.message}")
```

## Verification checklist

1. Create a blank Android app and add the Maven Central dependency.
2. Call configure() in Application.onCreate().
3. Verify getAppSprintId() returns a value after first launch.
4. Send login, purchase, and custom events. Confirm they appear in the dashboard.
5. Send an event offline, kill the app, relaunch with connectivity. Verify the event lands.
6. Call sendTestEvent() and confirm success is true.

---

## Docs navigation

Use the Markdown URLs when reading the docs programmatically. Use the HTML URLs when you need the interactive docs UI.

- [Overview](https://appsprint.app/docs) ([Markdown](https://appsprint.app/docs.md)) — Introduction to AppSprint
- [Quickstart](https://appsprint.app/docs/quickstart) ([Markdown](https://appsprint.app/docs/quickstart.md)) — Get up and running in 5 minutes
- [React Native](https://appsprint.app/docs/react-native) ([Markdown](https://appsprint.app/docs/react-native.md)) — React Native / Expo SDK reference
- [iOS (Swift)](https://appsprint.app/docs/ios-swift) ([Markdown](https://appsprint.app/docs/ios-swift.md)) — Native Swift SDK reference
- [Android (Kotlin)](https://appsprint.app/docs/android) ([Markdown](https://appsprint.app/docs/android.md)) — Native Android SDK reference
- [Flutter](https://appsprint.app/docs/flutter) ([Markdown](https://appsprint.app/docs/flutter.md)) — Flutter plugin reference
- [RevenueCat](https://appsprint.app/docs/revenuecat) ([Markdown](https://appsprint.app/docs/revenuecat.md)) — Webhook integration for subscription attribution
- [Superwall](https://appsprint.app/docs/superwall) ([Markdown](https://appsprint.app/docs/superwall.md)) — Webhook integration for paywall attribution
- [Apple Search Ads](https://appsprint.app/docs/apple-search-ads) ([Markdown](https://appsprint.app/docs/apple-search-ads.md)) — Campaign and keyword attribution
- [Google Ads](https://appsprint.app/docs/google-ads) ([Markdown](https://appsprint.app/docs/google-ads.md)) — Offline click conversion upload
- [TikTok Ads](https://appsprint.app/docs/tiktok-ads) ([Markdown](https://appsprint.app/docs/tiktok-ads.md)) — Events API server-side event forwarding
