Skip to main content
Supported on: Android SDK 1.0.33+
The feature flags module lets you enable or disable features remotely from the AppDNA Console. Flags are evaluated locally from cached config — no network call, no latency.

Check a Flag

if (AppDNA.features.isEnabled("dark_mode")) {
    enableDarkMode()
}
isEnabled() returns false by default if the flag does not exist or config has not loaded. The top-level convenience method AppDNA.isFeatureEnabled("dark_mode") is equivalent.

Read a Variant Value

Some flags carry a typed payload beyond on/off (e.g., a tier name or rollout percentage). Read the value with getVariant:
val tier = AppDNA.features.getVariant("pricing_tier") as? String
val percentage = (AppDNA.features.getVariant("rollout_percent") as? Number)?.toInt()
Returns Any? (string, number, boolean, list, or map). Cast to the type the Console stored.

Module Access

val features = AppDNA.features

Module Methods

MethodSignatureDescription
isEnabledisEnabled(flag: String): BooleanCheck if a feature flag is enabled
getVariantgetVariant(flag: String): Any?Get the typed value for a flag (string/number/bool/map)
onChangedonChanged(callback: (Map<String, Boolean>) -> Unit)Register a callback for flag changes

Listen for Changes

Register a callback to react when flags change after a live config update:
AppDNA.features.onChanged { flags ->
    if (flags["maintenance_mode"] == true) {
        showMaintenanceScreen()
    }
}
The callback receives the full Map<String, Boolean> snapshot — not just changed keys. Re-read whichever flags you care about and react accordingly.

Using Flags with Experiments

Feature flags and experiments work together. Gate a feature behind a flag, then run an experiment to test its impact:
if (AppDNA.features.isEnabled("new_workout_ui")) {
    val variant = AppDNA.experiments.getVariant("workout_ui_test")

    when (variant) {
        "compact" -> showCompactWorkoutUI()
        "detailed" -> showDetailedWorkoutUI()
        else -> showDefaultWorkoutUI()
    }
} else {
    showLegacyWorkoutUI()
}

Full Example

import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.paywall.PaywallContext
import android.app.Activity

class FeatureGate(private val activity: Activity) {

    fun checkAccess(feature: String, onLocked: () -> Unit, onUnlocked: () -> Unit) {
        if (AppDNA.features.isEnabled(feature)) {
            onUnlocked()
        } else {
            onLocked()
        }
    }
}

// Usage
val gate = FeatureGate(activity)

gate.checkAccess(
    feature = "ai_suggestions",
    onLocked = {
        AppDNA.presentPaywall(
            activity = activity,
            id = "premium_paywall",
            context = PaywallContext(placement = "feature_gate"),
        )
    },
    onUnlocked = {
        showAiSuggestions()
    },
)
Feature flags are managed in the Console under Settings → Feature Flags. Toggle a flag on or off and it takes effect on the next SDK config refresh (within the TTL window, default 1 hour) or immediately via the live Firestore listener.

Next Steps