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.
Dependency
Section titled “Dependency”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.
Permissions
Section titled “Permissions”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.
Runtime permission flow
Section titled “Runtime permission flow”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+.
- Request
ACCESS_FINE_LOCATION+ACCESS_COARSE_LOCATIONtogether (single dialog). - On API 29+, request
ACCESS_BACKGROUND_LOCATIONseparately. This always opens Settings on API 30+. - 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.
Foreground service notification
Section titled “Foreground service notification”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.
Initialise once
Section titled “Initialise once”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().
When start() will fail
Section titled “When start() will fail”Beekon.start() is suspend and throws typed errors:
| Throws | When |
|---|---|
BeekonError.NotInitialised | Beekon.initialize(context) was never called |
BeekonError.NotConfigured | Beekon.configure(...) was never called |
BeekonError.PermissionDenied | runtime location permission not granted |
BeekonError.NoGmsAvailable | device 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.
Background reliability
Section titled “Background reliability”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.
- iOS setup — if you also ship for iOS.
- Background execution — what’s actually keeping your service alive.
- Lifecycle & states — the state machine driving
Beekon.state.