Skip to navigation

Android OpenFeature provider

Beta
View as Markdown

The Unleash OpenFeature Android provider lets Android applications evaluate Unleash feature flags through the OpenFeature API.

The provider wraps the Unleash Android SDK and uses the same frontend SDK behavior for fetching evaluated flags, polling, and metrics. Because the Android SDK is a frontend SDK, this is a static-context provider: you set the evaluation context on the OpenFeature API instead of passing it per evaluation, and context changes trigger a refetch of the flag configuration from Unleash.

Requirements

  • Android API level 21 or higher (API level 23 recommended)

Installation

Add the provider to your module’s Gradle dependencies. The provider exposes the OpenFeature Kotlin SDK and the Unleash Android SDK as API dependencies, so you don’t need to add them separately.

implementation("io.getunleash:unleash-openfeature-android-provider:<version>")

Find the latest version in the provider releases.

Configuration

Create an UnleashOpenFeatureProvider with your Android application context and an UnleashConfig, then register it with OpenFeature. The provider builds and owns the Unleash client. Connect to the Frontend API or Unleash Edge with a frontend token.

import dev.openfeature.sdk.ImmutableContext
import dev.openfeature.sdk.OpenFeatureAPI
import io.getunleash.android.UnleashConfig
import io.getunleash.openfeature.android.UnleashOpenFeatureProvider
val config = UnleashConfig
.newBuilder("my-android-app")
.proxyUrl("<YOUR_UNLEASH_URL>/api/frontend")
.clientKey("<YOUR_FRONTEND_API_TOKEN>")
.build()
val provider = UnleashOpenFeatureProvider(
androidContext = applicationContext,
unleashConfig = config,
)
// Call from a coroutine
OpenFeatureAPI.setProviderAndWait(
provider,
initialContext = ImmutableContext(targetingKey = "user-123"),
)

You can configure the UnleashConfig with the same options you use with the Unleash Android SDK client.

setProviderAndWait registers the provider, applies the initial context, and waits for the first flag configuration to arrive, so evaluations made immediately after registration use your context. The context is applied before the client starts, so the first fetch already carries it.

The wait is bounded because the SDK reports readiness only once a non-empty flag set reaches its cache. A failed fetch, a project with no flags, or polling disabled with pollingStrategy.enabled(false) never produce one. The default timeout is three seconds. To change it, pass initializationTimeout to the provider constructor:

import kotlin.time.Duration.Companion.seconds
val provider = UnleashOpenFeatureProvider(
androidContext = applicationContext,
unleashConfig = config,
initializationTimeout = 5.seconds,
)

If the wait times out, the provider logs a warning and registers anyway. Evaluations return false or the default value until a later poll succeeds. After that, the SDK continues polling for flag updates in the background.

On a cold start with no connectivity, setProviderAndWait suspends for the full timeout, so don’t block your first frame on it.

Evaluate a flag

Build an OpenFeature client and evaluate flags through the OpenFeature API:

val client = OpenFeatureAPI.getClient()
val enabled = client.getBooleanValue("my-feature", false)

The provider supports all OpenFeature evaluation methods. Boolean evaluation uses the flag’s enabled state and returns false if the flag doesn’t exist, regardless of the default value you supply. All other types resolve from the payload of the flag’s variant:

  • String values accept string and csv payloads.
  • Integer and double values accept number payloads.
  • Object values accept json payloads.

A missing flag, a disabled variant, or a variant without a payload returns the default value. A payload of the wrong type returns the default value with a type mismatch error, and a payload that can’t be parsed returns the default value with a parse error. The detail methods, such as getStringDetails, also report the assigned variant name, even when they return the default value.

Update the evaluation context

The provider ignores the per-evaluation context parameter. To change the context, update it on the OpenFeature API. The Unleash client refetches the flag configuration for the new context, and setEvaluationContextAndWait returns when the refetch completes:

import dev.openfeature.sdk.Value
// Call from a coroutine
OpenFeatureAPI.setEvaluationContextAndWait(
ImmutableContext(
targetingKey = "user-456",
attributes = mapOf("plan" to Value.String("pro")),
)
)

Context mapping

The provider maps the OpenFeature evaluation context to an Unleash context.

If you set a targeting key, the provider maps it to userId. The targeting key takes precedence over a userId attribute set on the evaluation context. The userId, sessionId, and remoteAddress attributes map to the corresponding top-level Unleash context fields.

The provider adds all other scalar attributes, such as strings, numbers, booleans, and dates, to the Unleash context properties as strings. It discards list, structure, and null attributes.

Shutdown

Shut down OpenFeature when you no longer need the provider. This also closes the underlying Unleash client.

// Call from a coroutine
OpenFeatureAPI.shutdown()

Provider events

The provider doesn’t define events of its own. The OpenFeature Kotlin SDK reports provider status, such as ready, reconciling, and error, through OpenFeatureAPI.statusFlow around initialization and context changes.

Example

To try the provider, clone the provider repository and run the example application from Android Studio. Replace the Frontend API URL and client key in MainActivity.kt with your own.