Skip to content

Installation

Requirements

  • Android minSdk 24, compiled against API 34+
  • Kotlin ≥ 1.9, JVM target 17
  • kotlinx-coroutines — the API is suspend functions and Flows

See Compatibility for the full support matrix.

Add the dependency

app/build.gradle.kts
dependencies {
implementation("dev.bgeo:background-geolocation:0.1.0")
}

Both dev.bgeo:background-geolocation (this facade) and dev.bgeo:bgeo-android (the engine) are on Maven Central, so mavenCentral() in your repositories is all the resolution config you need — the engine arrives transitively, as do Play Services Location and OkHttp.

Three things Gradle cannot do for you follow.

1. attach() in Application.onCreate — mandatory

MyApplication.kt
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
BackgroundGeolocation.attach(this)
}
}
AndroidManifest.xml
<application android:name=".MyApplication" ...>

This is the single most important integration fact for this SDK.

Android restarts your process for boot, geofence and foreground-service events, and Application.onCreate is the only hook that reliably runs in every one of them. attach() wires the engine to the process once, for the process’s whole lifetime.

Put it in an Activity instead and the SDK will appear to work — right up until a real background event arrives while no Activity is alive, at which point nothing receives it. This is also why this SDK, unlike the React Native and Flutter ones, needs no headless-task registration: your process coming back IS the headless path.

2. Declare ACCESS_BACKGROUND_LOCATION yourself

AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

The engine deliberately omits this one from its own manifest, even though it declares the rest (fine/coarse location, activity recognition, the foreground-service permissions, boot and notifications). Google Play policy requires the app to own both the manifest declaration and the Play Console background-location disclosure — a library that declared it for you would put your listing at risk without your knowing.

Everything else is merged from the engine’s manifest; you do not need to repeat it.

3. License key in the manifest

The key is not a Config property. It is read from your app’s manifest at launch:

AndroidManifest.xml
<application>
<meta-data android:name="com.bgeo.license" android:value="BGEO1..." />
</application>

In a release build, a missing, invalid, expired or mismatched key makes ready() and start() throw a BGeoException with a LICENSE_* code. A debuggable build always runs unlicensed, in evaluation mode, whatever the key says.

That asymmetry is worth internalising now, because it produces the single most confusing bug report this SDK gets: tracking works perfectly all through development and refuses to start the first time someone installs a release build. See License keys.

Proguard / R8

Nothing to add. The engine ships its own consumer-rules.pro, and so does this facade, so the classes reflection and the manifest reach are kept automatically in minified builds.

Verify the install

lifecycleScope.launch {
val state = BackgroundGeolocation.ready(Config(distanceFilter = 10.0))
Log.d("BGeo", "ready, enabled=${state.enabled}")
}

A ready() that returns without throwing means the engine is attached, the manifest merged, and (in a release build) the license accepted. From here, Permissions is the next requirement — start() without location permission will not produce fixes.