> ## Documentation Index
> Fetch the complete documentation index at: https://usefantasma.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Android SDK

> Install and use FantasmaSDK for Android.

# Fantasma Android SDK

`FantasmaSDK` for Android is the Android-first Kotlin client for Fantasma's
event ingest API.

Android parity is at the event-contract and runtime-behavior level, not the
exact public API shape. The iOS SDK exposes a static `Fantasma` facade; Android
uses an instance-based `FantasmaClient` API because that fits Android and
Kotlin usage better.

Shared ingest and queue behavior lives on the [SDK behavior](/mintlify/sdk-behavior)
page.

## Install

The Android build lives under:

```text theme={null}
sdks/android
```

The library module is:

```text theme={null}
:fantasma-sdk
```

Current build requirements:

* Android `minSdk 26`
* Java 17
* Kotlin 2.0.21

## Usage

```kotlin theme={null}
import android.app.Application
import com.fantasma.sdk.FantasmaClient
import com.fantasma.sdk.FantasmaConfig
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class DemoApplication : Application() {
    private lateinit var fantasma: FantasmaClient

    override fun onCreate() {
        super.onCreate()
        fantasma = FantasmaClient(
            context = this,
            config = FantasmaConfig(
                serverUrl = "http://10.0.2.2:8081",
                writeKey = "<ingest-key-from-provision-project>",
            ),
        )

        CoroutineScope(Dispatchers.Main).launch {
            fantasma.track("app_open")
        }
    }
}
```

## Public API

* `FantasmaClient(context, FantasmaConfig(serverUrl, writeKey))`
* `track(eventName)`
* `flush()`
* `clear()`
* `close()`

`track()` and `flush()` are suspend functions and throw typed
`FantasmaException` failures. `close()` is idempotent, and any later `track()`,
`flush()`, or `clear()` call on that closed client throws
`FantasmaException.ClosedClient`.

## Android-Specific Notes

* Android uses an instance-based `FantasmaClient` API rather than a static facade.
* The SDK auto-populates `platform = "android"`, `device`, `app_version`, `os_version`, and `locale`.
* `device` emits `phone`, `tablet`, or `unknown` from the Android runtime form-factor snapshot.
* `track()` and `flush()` are suspend functions and throw typed `FantasmaException` failures.
* `close()` is idempotent, and any later `track()`, `flush()`, or `clear()` call on that closed client throws `FantasmaException.ClosedClient`.
* In addition to the shared upload triggers, the SDK also attempts uploads when the app enters background.
* The SDK persists one app-local install identifier, reuses it across destinations, and rotates it on `clear()` without mutating already queued rows.
* Clients created with the same normalized destination share one process-local runtime.
* Creating a client with a different normalized destination supersedes the previously active destination for the process after the current upload boundary, matching the Swift SDK's single-destination behavior.
* Older Android client handles should be treated as replaced once a different destination is created; future `track()`, `flush()`, and `clear()` calls on a superseded handle throw `FantasmaException.ClosedClient`, and the superseded runtime retires itself without requiring an explicit `close()` on the old handle.
