Setup SDK (Android)
Get started using Distribution for Android in under 10 minutes
com.emergetools.distribution is a Android library that simplifies the process of distributing new app versions and checking for updates. It provides an easy-to-use API to verify if a new version is available and handles the update process seamlessly, ensuring your team members are always on the latest release.
Quick setup (~10 minutes)
Install the SDK
Latest versions:
// app-module build.gradle.kts
dependencies {
implementation("com.emergetools.distribution:distribution:<latest_version>")
}
Configure the SDK
The SDK can be configured via:
- The emerge
gradle
plugin - Directly using
gradle
- Manually in
AndroidManifest.xml
The build distribution API key is included in prerelease versions of an app. It allows that app to determine if there are updates available and download those updates if so. The key can be found here
via manifestPlaceholders
// app-module build.gradle.kts
android {
// ...
defaultConfig {
// ...
manifestPlaceholders["emerge.distribution.apiKey"] = ""
}
buildTypes {
// ...
staging {
// ...
manifestPlaceholders["emerge.distribution.apiKey"] = System.getenv("DISTRIBUTION_API_KEY")
}
}
}
via Gradle plugin
Gradle plugin support pending
Follow #297 for updates.
// app-module build.gradle.kts
plugins {
id("com.emergetools.android")
}
emerge {
// Emerge uses the EMERGE_API_TOKEN env variable by default if you don't set a value explicitly.
apiToken.set(System.getenv("EMERGE_API_TOKEN"))
// ...
distribution {
enabledVariants.set("staging")
apiKey.set("<DISTRIBUTION_API_KEY>")
}
}
Checking for an update
In order to check for updates you call the Distribution.checkForUpdate(context)
method. This is an async method which checks if an update is available. See also the Distribution API.
An explicit button
Here is an example of how checkForUpdate
can be wired up to an explicit button.
@Composable
fun MyCustomUpdaterButton() {
val context = LocalContext.current
Box {
val scope = rememberCoroutineScope()
var isLoading by remember { mutableStateOf(false) }
var status by remember { mutableStateOf<UpdateStatus?>(null) }
Button(onClick = {
scope.launch {
isLoading = true
status = null
status = Distribution.checkForUpdate(context)
// If a new release is available download it:
val myStatus = status
if (myStatus is UpdateStatus.NewRelease) {
Distribution.downloadUpdate(context, myStatus.info)
}
isLoading = false
}
}) {
when (isLoading) {
true -> Text(text = "Loading...")
false -> when (status) {
is UpdateStatus.UpToDate -> Text(text = "Up to date!")
is UpdateStatus.Error -> Text(text = (status as UpdateStatus.Error).message)
is UpdateStatus.NewRelease -> Text(text = "New release!")
else -> Text(text = "Check for updates")
}
}
}
}
}
SDK initialization
Automatic initialization
Distribution relies on the Androidx startup library to auto-initialize the Distribution SDK as part of your app's startup.
Disable automatic initialization
To disable automatic initialization add the following snippet to your app's AndroidManifest.xml
:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data android:name="com.emergetools.distribution.DistributionInitializer"
tools:node="remove" />
</provider>
You may need to add a direct dependency on theandroidx.startup:startup-runtime
library if the app does not already have such a dependency.
// app-module build.gradle.kts
dependencies {
implementation("androidx.startup:startup-runtime:<latest_version>")
}
Follow the Manual initialization steps below to ensure that Distribution is initialized.
Manual initialization
To manually initialize Distribution call Distribution.init(context)
. For example:
import com.emergetools.distribution.Distribution
class MyApp : Application() {
override fun onCreate() {
Distribution.init(this)
}
}
import com.emergetools.reaper.Reaper;
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
Reaper.init(this);
}
}
A common case when manual initialization is required is when androidx.startup.InitializationProvider
has been globally disabled by the following snippet being included in the AndroidManifest.xml
:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="remove">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
Examples
Updated 26 days ago