Skip to content

Android setup

The Beekon .aar declares the permissions it needs in its own manifest, and they merge into your app at build time. You still need to request the dangerous permissions at runtime and provide a NotificationConfig for the foreground service.

app/build.gradle.kts
android {
defaultConfig {
minSdk = 24 // Beekon's minimum
}
}
dependencies {
implementation("io.github.wayqteam:beekon:0.0.1")
}

The module requires JDK 17 to build and ships with explicitApi() enforced — your consuming app’s Kotlin version doesn’t have to match, but Kotlin 2.x is recommended.

These are in Beekon’s manifest already; if you want to see them in your merged manifest, add them to app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

FOREGROUND_SERVICE_LOCATION is required from Android 14 (API 34). POST_NOTIFICATIONS is required from Android 13 (API 33) for the foreground-service notification to be visible.

Android forces a three-step prompt sequence — you cannot ask for background location without first having foreground location, and notifications need their own grant on Android 13+.

  1. Request ACCESS_FINE_LOCATION + ACCESS_COARSE_LOCATION together (single dialog).
  2. On API 29+, request ACCESS_BACKGROUND_LOCATION separately. This always opens Settings on API 30+.
  3. On API 33+, request POST_NOTIFICATIONS.

The Compose sample at beekon-android/sample ships a LocationPermissions composable that walks through this exact sequence — copy from there if you don’t already have a permissions helper.

BeekonConfig.notification is required — Android requires a visible foreground-service notification while location is being captured in the background.

NotificationConfig(
channelId = "beekon-tracking",
channelName = "Tracking", // shown in Settings → Notifications
notificationId = 7411, // any non-zero int unique to your app
title = "Beekon", // notification title
text = "Tracking your location", // notification body
smallIcon = R.drawable.ic_stat_beekon, // monochrome white-on-transparent
)

Beekon creates the NotificationChannel for you on Android 8+. Pick a channelId that’s specific to this notification — users can disable individual channels in Settings.

class App : Application() {
override fun onCreate() {
super.onCreate()
Beekon.initialize(this)
Beekon.configure(
BeekonConfig(
preset = Preset.Balanced,
notification = NotificationConfig(
channelId = "beekon-tracking",
channelName = "Tracking",
notificationId = 7411,
title = "Beekon",
text = "Tracking your location",
smallIcon = R.drawable.ic_stat_beekon,
),
),
)
}
}

initialize is idempotent — calling it twice is harmless. configure can be called again to change preset or override fields; it takes effect on the next start().

Beekon.start() is suspend and throws typed errors:

ThrowsWhen
BeekonError.NotInitialisedBeekon.initialize(context) was never called
BeekonError.NotConfiguredBeekon.configure(...) was never called
BeekonError.PermissionDeniedruntime location permission not granted
BeekonError.NoGmsAvailabledevice has no Google Play Services (v1 is GMS-only)
BeekonError.ServiceFailed(cause)foreground service failed to start (e.g. quota, OEM kill)
BeekonError.InternalError(cause)anything else

See Errors for what to do about each.

Once start() returns, Beekon runs a foreground service with FOREGROUND_SERVICE_LOCATION type and re-subscribes to FusedLocationProviderClient after Doze, app-standby, and OEM-killer events. A boot receiver auto-restarts tracking after device reboot if it was previously enabled.

There’s nothing to do on your side — but be aware that aggressive OEM battery managers (Xiaomi, Huawei, Samsung, OPPO, Vivo) can still kill the service. The dontkillmyapp.com matrix lists the per-OEM workarounds you may need to surface to users.