Skip to content

Installation

Requirements

  • Flutter ≥ 3.22, Dart ≥ 3.4 (null-safety, Future/Stream-based API)
  • iOS ≥ 15.5, Android minSdk 24

See Compatibility for the full support matrix.

Install the package

Terminal window
flutter pub add bgeo_background_geolocation

There is no manual native linking step — the Flutter plugin system wires up the Android/iOS platform code on both platforms. What’s left is native project configuration: the deployment target and Info.plist keys on iOS, a Maven repo and manifest permissions on Android.

Import convention

Import the package with an as bg prefix:

import 'package:bgeo_background_geolocation/bgeo_background_geolocation.dart' as bg;

This is the recommended default because the SDK’s own State class collides with Flutter’s State<T> widget-state class otherwise. Reference everything through the prefix — bg.BackgroundGeolocation, bg.Config, bg.State, etc.

If your code never needs to name the SDK’s State snapshot type directly (for example, if you only read state.enabled off the return value of ready()/start()/stop() without ever declaring a bg.State variable), a lighter-weight alternative is to hide it instead:

import 'package:bgeo_background_geolocation/bgeo_background_geolocation.dart' hide State;

as bg is the safer default since it scales to any usage; hide State is fine for small apps that only touch the plugin from a handful of call sites.

iOS setup

Deployment target

BGeo’s vendored BGeoCore.xcframework has a floor of iOS 15.5. Set it in both places Flutter apps track a deployment target:

ios/Podfile
platform :ios, '15.5'

And the Runner target’s iOS Deployment Target build setting in Xcode (target → Build SettingsiOS Deployment Target). Then install pods:

Terminal window
cd ios && pod install

Info.plist keys

Add these keys to ios/Runner/Info.plist:

ios/Runner/Info.plist
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Explain why your app tracks location in the background.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Explain why your app needs your current location.</string>
<key>NSMotionUsageDescription</key>
<string>Motion activity is used to detect movement and pause tracking when stationary.</string>
<key>BGeoLicense</key>
<string>BGEO1...</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
KeyWhy it’s required
NSLocationAlwaysAndWhenInUseUsageDescriptionShown when requesting Always authorization, needed for background tracking.
NSLocationWhenInUseUsageDescriptionShown for the foreground/“When In Use” step of the authorization prompt.
NSMotionUsageDescriptionShown when the engine reads Core Motion activity (moving/still) to drive the motion state machine.
BGeoLicenseYour production license key (or the literal string EVALUATION for local dev). See License keys.
UIBackgroundModeslocationTells iOS your app performs background location updates; without it, background delivery is silently capped.

Write real justification strings — App Store review rejects vague usage descriptions. See Permissions & background location for the full authorization/review guidance.

Enable the Background Modes capability in Xcode

The Info.plist entry above must be paired with the capability enabled in the Xcode project:

  1. Open ios/Runner.xcworkspace in Xcode.
  2. Select the Runner target → Signing & Capabilities.
  3. Click + Capability, choose Background Modes.
  4. Check Location updates.
Xcode's Signing & Capabilities tab for the example app target, with the Background Modes capability added and 'Location updates' checked, plus a Location (Always) usage description below it.

Android setup

Add the local Maven repo

The closed engine ships as an AAR in a local Maven repo inside the plugin package. Gradle repository declarations are per-project, not inherited from a dependency project, so your app’s own android/app/build.gradle.kts (or .gradle) must add that repo itself:

android/app/build.gradle.kts
repositories {
maven { url = uri("${project(":bgeo_background_geolocation").projectDir}/libs") }
}
android/app/build.gradle (Groovy)
repositories {
maven { url "${project(':bgeo_background_geolocation').projectDir}/libs" }
}

Using the Flutter-generated project(':bgeo_background_geolocation') handle (rather than a relative path into node_modules-style vendoring) resolves correctly whether the plugin is installed from pub.dev (under ~/.pub-cache) or referenced as a local path dependency.

License meta-data

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

See License keys for evaluation vs. production keys and how expiry works.

Declare the background-location permission

Google Play policy requires the app, not a library, to own the background-location declaration (and the corresponding Play Console disclosure), so ACCESS_BACKGROUND_LOCATION is deliberately not auto-declared by the plugin. Add it to your app manifest:

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

Permissions merged automatically

The engine AAR’s manifest merges the rest of the permissions the plugin needs directly into your app:

PermissionWhy
ACCESS_FINE_LOCATIONForeground GPS fixes.
ACCESS_COARSE_LOCATIONNetwork/cell-grade location fallback.
ACTIVITY_RECOGNITIONDrives the moving/still motion state machine via Play Services.
FOREGROUND_SERVICERequired to run the tracking foreground service.
FOREGROUND_SERVICE_LOCATIONAndroid 14+ typed foreground-service permission for the location service type.
RECEIVE_BOOT_COMPLETEDResumes tracking after reboot when startOnBoot is enabled.
WAKE_LOCKKeeps the device awake briefly for background processing.
POST_NOTIFICATIONSAndroid 13+ permission for the required tracking notification.
INTERNET / ACCESS_NETWORK_STATENative HTTP upload of queued locations.

See Permissions & background location for the runtime request flow and the Play Console disclosure requirement.

Gradle notes

  • minSdk 24, compileSdk 36.
  • The plugin’s Android namespace is com.bgeo.flutter; the vendored engine AAR owns the com.bgeo namespace separately, so there’s no resource/R-class clash.

License key

Debuggable builds and the iOS simulator run without a license key — set the manifest/Info.plist value to the literal string EVALUATION for local dev. Release builds require a real key — see License keys for where it goes and how it’s validated.

Verify the install

Build and run the app on a device or simulator, then confirm the plugin loaded:

import 'package:bgeo_background_geolocation/bgeo_background_geolocation.dart' as bg;
final state = await bg.BackgroundGeolocation.getState();
print(state.enabled); // false is expected before ready()/start()

If this resolves without throwing, the plugin linked correctly on that platform. See getState() for the full return shape, and Quickstart for wiring up ready()/start() and your first location events.