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

# Android Quickstart

> Configure, identify, and track in 5 minutes

<Info>
  **Supported on:** Android SDK `1.0.33+`
</Info>

This guide walks you through configuring the AppDNA SDK, identifying users, and tracking your first event.

## 1. Configure the SDK

Initialize AppDNA as early as possible in your app lifecycle. Place the configuration call in your `Application.onCreate()` method:

```kotlin theme={null}
import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.AppDNAOptions
import ai.appdna.sdk.Environment
import ai.appdna.sdk.LogLevel
import android.app.Application

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

        AppDNA.configure(
            context = this,
            apiKey = "adn_live_xxx",
            environment = Environment.PRODUCTION,
            options = AppDNAOptions(logLevel = LogLevel.DEBUG)
        )
    }
}
```

<Info>
  Firebase is automatically initialized from `google-services-appdna.json` on Android. You do not need to call any Firebase initialization method manually. Ensure that `google-services-appdna.json` is in your `app/` directory and the Google Services plugin is applied (see [Installation](/sdks/android/installation)).
</Info>

<Note>
  If your app already uses Firebase for your own services (Analytics, Crashlytics, Realtime Database), AppDNA automatically creates a separate named Firebase instance. Your existing Firebase setup is not affected.
</Note>

<Warning>
  Call `AppDNA.configure(...)` exactly once before using any other SDK methods. Calling it multiple times will result in undefined behavior. Always call it in `Application.onCreate()`, not in an Activity.
</Warning>

### Configuration Options

The `AppDNAOptions` data class lets you customize SDK behavior:

| Parameter       | Type       | Default            | Description                                      |
| --------------- | ---------- | ------------------ | ------------------------------------------------ |
| `flushInterval` | `Long`     | `30L` (seconds)    | Seconds between automatic event flushes          |
| `batchSize`     | `Int`      | `20`               | Number of events to batch before flushing        |
| `configTTL`     | `Long`     | `3600L` (seconds)  | Seconds before cached config is considered stale |
| `logLevel`      | `LogLevel` | `LogLevel.WARNING` | Verbosity of SDK console logs                    |

### Environment

The `Environment` enum controls which backend the SDK targets:

| Value                    | Endpoint                | Description                                                                                                                                                    |
| ------------------------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Environment.PRODUCTION` | `https://api.appdna.ai` | Production API and configuration                                                                                                                               |
| `Environment.SANDBOX`    | `https://api.appdna.ai` | Same endpoint as production — sandbox is routed via your `adn_test_*` API-key prefix. Use a test key from the Console to send traffic to the sandbox pipeline. |

### Log Level

The `LogLevel` enum controls Logcat log verbosity:

| Value              | Raw Value | Description                  |
| ------------------ | --------- | ---------------------------- |
| `LogLevel.NONE`    | `0`       | No logging                   |
| `LogLevel.ERROR`   | `1`       | Errors only                  |
| `LogLevel.WARNING` | `2`       | Errors and warnings          |
| `LogLevel.INFO`    | `3`       | Errors, warnings, and info   |
| `LogLevel.DEBUG`   | `4`       | All messages including debug |

<Info>
  Use `LogLevel.DEBUG` during development to see all SDK activity in Logcat. Switch to `LogLevel.WARNING` or `LogLevel.NONE` for production builds.
</Info>

## 2. Wait for Ready State

The SDK fetches remote configuration asynchronously. Use `onReady` to know when the SDK is fully initialized:

```kotlin theme={null}
AppDNA.onReady {
    Log.d("AppDNA", "SDK ready — remote config loaded")
}
```

## 3. Identify Users

Once a user signs in, call `identify` to associate events with their user ID:

```kotlin theme={null}
AppDNA.identify(
    userId = "user-123",
    traits = mapOf(
        "plan" to "premium",
        "signup_date" to "2025-01-15"
    )
)
```

<Note>
  Traits are merged with any previously set traits. You do not need to pass all traits on every call -- only the ones that have changed.
</Note>

## 4. Track Events

Track user actions with `track`:

```kotlin theme={null}
AppDNA.track(
    event = "workout_completed",
    properties = mapOf(
        "duration" to 45,
        "type" to "strength"
    )
)
```

Events are batched and flushed automatically based on your `flushInterval` and `batchSize` settings.

## 5. Flush Events Manually

Force an immediate flush of all queued events:

```kotlin theme={null}
AppDNA.flush()
```

This is useful before the app enters the background or when you need to ensure events are sent immediately.

## 6. Set User Consent

Control whether the SDK collects and sends analytics data:

```kotlin theme={null}
AppDNA.setConsent(analytics = true)
```

<Warning>
  When `analytics` is set to `false`, events are silently dropped and not queued. No data is sent to AppDNA servers until consent is granted.
</Warning>

## 7. Change Log Level at Runtime

You can adjust the log level after configuration without restarting the app:

```kotlin theme={null}
AppDNA.setLogLevel("debug")
```

Accepted values: `"none"`, `"error"`, `"warning"`, `"info"`, `"debug"`.

## 8. Remote Config and Feature Flags

Retrieve server-side configuration values:

```kotlin theme={null}
val welcomeMessage = AppDNA.getRemoteConfig("welcome_message")
```

Check whether a feature flag is enabled:

```kotlin theme={null}
val darkModeEnabled = AppDNA.isFeatureEnabled("dark_mode")
```

## 9. Experiments

Get the variant assigned to a user for an experiment:

```kotlin theme={null}
val variant = AppDNA.getExperimentVariant("paywall_test")
```

Check if the user is in a specific variant:

```kotlin theme={null}
val isInVariantB = AppDNA.isInVariant("paywall_test", "b")
```

## 10. Session Data

Store cross-module session data that can be used in template interpolation across onboarding flows, paywalls, and in-app messages:

```kotlin theme={null}
// Store session data
AppDNA.setSessionData(key = "selected_plan", value = "premium")
AppDNA.setSessionData(key = "referral_code", value = "FRIEND2026")

// Retrieve session data
val plan = AppDNA.getSessionData(key = "selected_plan") // "premium"

// Clear all session data
AppDNA.clearSessionData()
```

Session data values are accessible in Console-configured content using template syntax: `{{session.selected_plan}}`.

## 11. Reset on Logout

When a user signs out, call `reset` to clear identity-scoped state:

```kotlin theme={null}
AppDNA.reset()
```

This clears the identified user, resets experiment exposures, clears in-session message/survey state, and stops the web-entitlement observer. The anonymous device identifier persists across `reset()` calls. Call `AppDNA.flush()` separately if you also want to drain the event queue before logout.

<Check>
  You now have the SDK configured, user identification, event tracking, remote config, experiments, and session data working. Continue to the module-specific guides for [Push Notifications](/sdks/android/push), [Billing](/sdks/android/billing), [Onboarding](/sdks/android/onboarding), and [Paywalls](/sdks/android/paywall).
</Check>
