Flutter setup
The Flutter plugin is a thin pass-through over the two native libraries. It uses Pigeon for type-safe MethodChannel + EventChannel and never participates in the persistence write path — that lives in the native libraries because background runtimes aren’t guaranteed to be alive.
Add the dependency
Section titled “Add the dependency”dependencies: beekon_flutter: ^0.0.1flutter pub getFlutter 3.44+ is recommended (default SwiftPM). On 3.32–3.43 enable it once: flutter config --enable-swift-package-manager. CocoaPods is not supported — Beekon’s iOS dependency resolves via SwiftPM only.
Android side
Section titled “Android side”The plugin pulls in io.github.wayqteam:beekon automatically. You need to repeat its permissions in your example/app manifest if you want them visible there, and enable core library desugaring if you target API 24–25.
Permissions
Section titled “Permissions”<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" />Core library desugaring
Section titled “Core library desugaring”android { compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 isCoreLibraryDesugaringEnabled = true } defaultConfig { minSdk = 24 }}
dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")}If you target minSdk = 26 or higher, you can omit isCoreLibraryDesugaringEnabled and the desugar_jdk_libs dependency.
iOS side
Section titled “iOS side”<!-- ios/Runner/Info.plist --><key>NSLocationWhenInUseUsageDescription</key><string>Used to show your live position in the app.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key><string>Used to keep tracking your trips when the app is in the background.</string>
<key>UIBackgroundModes</key><array> <string>location</string></array>iOS 15 minimum. The plugin’s iOS dependency resolves via SwiftPM — there’s no Podfile config to maintain.
Initialise once
Section titled “Initialise once”import 'package:beekon_flutter/beekon_flutter.dart';
Future<void> bootstrap() async { await Beekon.instance.initialize(); await Beekon.instance.configure( const BeekonConfig( preset: BeekonPreset.balanced, androidNotification: AndroidNotification( channelId: 'beekon-tracking', channelName: 'Tracking', notificationId: 7411, title: 'Beekon', text: 'Tracking your location', smallIcon: 'ic_launcher', ), ), );}androidNotification is required when running on Android — if missing, start() throws NotConfigured. iOS ignores it.
smallIcon is the resource name (e.g. 'ic_launcher', 'ic_stat_beekon') — Beekon resolves it via getIdentifier() at runtime. The drawable must exist in your Android res/drawable* folders.
Permissions
Section titled “Permissions”Beekon does not request runtime permissions — your app drives the dialog (use permission_handler or platform-channel calls of your own). Android needs locationAlways + notification; iOS needs locationAlways (with the standard two-step whenInUse → always dance).
Start tracking and observe
Section titled “Start tracking and observe”try { await Beekon.instance.start();} on PermissionDenied { // request runtime permissions; on iOS, drive the Always prompt} on NoGmsAvailable { // Android device has no Google Play Services — Beekon v1 doesn't support non-GMS}
Beekon.instance.state.listen((BeekonState s) { // Idle, Starting, Tracking, Paused(reason), Stopped});
Beekon.instance.positions.listen((Position p) { // emits only while Flutter is alive — read history(...) for persisted points});History reads cross the channel (history(from:, to:) returns Future<List<Position>>); the position stream does not buffer across Flutter-engine restarts.
When start() will fail
Section titled “When start() will fail”| Throws | Meaning |
|---|---|
PermissionDenied | runtime location permission missing |
LocationServicesDisabled | iOS-side: Settings → Privacy → Location Services is off |
NoGmsAvailable | Android device has no Google Play Services |
NotInitialised | initialize() was never called |
NotConfigured | configure(...) was never called (or androidNotification is missing on Android) |
ServiceFailed(cause) | Android foreground-service start failure |
InternalError(cause) | anything else — log and surface |
See Errors for full handling.
- Lifecycle & states — the state machine you’ll observe.
- Background execution — what’s keeping your app alive on each platform.
- Persistence & history — what the
historyquery returns.