Skip to content

Example app

The SDK’s source repo ships a full example app under example/ — a dev/debug tool, not a template to copy into your project. It depends on the plugin the same way a real consuming app would: a path: dependency in its pubspec.yaml, resolved straight from the repo’s lib/, so editing plugin source is immediately reflected in the example on the next hot restart without requiring a pub publish step.

Unlike the React Native example (a three-tab map/settings/logs app), the Flutter example is deliberately minimal: a single screen that exercises every major API surface — lifecycle, permissions, a one-shot fix, pace control, manual sync, and the native log — without a map view or a persisted-config editor.

Running it

Terminal window
cd example
flutter pub get
flutter run

By default the app runs local-only: no url is set, so fixes are filtered, persisted, and delivered to onLocation, but nothing uploads. To point it at a server, pass the URL at build/run time via --dart-define:

Terminal window
flutter run --dart-define=BGEO_URL=https://your-server.example.com/locations

String.fromEnvironment('BGEO_URL') reads that value at compile time; when it’s empty, the example passes url: null to Config, which is exactly persist-only mode (see the HTTP guide).

Both a debug Android build and an iOS simulator/debug build run unlicensed — no real license key is required. The example’s manifest/Info.plist license entries are already set to the literal string EVALUATION on both platforms, which is honoured identically to an unset key in a debug build; swap in a real BGEO1... key only if you build a release binary from this example.

Tour of the screen

The entire UI is one Scaffold: a switch, a row of buttons, and a scrolling log list.

Tracking switch

A SwitchListTile at the top reflects state.enabled — the boolean every lifecycle method (ready(), start(), stop()) resolves with. Flipping it calls start() or stop() and updates the switch from the returned State, rather than tracking a separate local boolean:

Future<void> _toggleTracking(bool value) async {
final state =
value ? await BackgroundGeolocation.start() : await BackgroundGeolocation.stop();
setState(() => _enabled = state.enabled);
}

Action buttons

A Wrap of five buttons covers the rest of the one-shot API surface:

  • Request Permission — calls requestPermission() directly; the resolved authorization status isn’t displayed, just requested.
  • Get Current Position — calls getCurrentPosition() and appends the resulting coordinates to the log.
  • Change Pace — calls changePace(true), forcing the engine into the moving state regardless of actual motion.
  • Sync — calls sync() to drain the upload queue on demand.
  • Log → console — calls getLog() and prints every entry’s timestamp, source/event tag, and message via debugPrint, rather than rendering them on screen.

Event log

Six listeners are wired up once in initState/_initonLocation, onMotionChange, onHeartbeat, onHttp, onProviderChange, and onConnectivityChange — each formatting a one-line summary and prepending it to an in-memory list rendered by a ListView.builder below the buttons, newest-first. This is a live event feed, not the native log store: it only shows events received while the screen is mounted, and it’s cleared on hot restart. For the native, persisted log store (what getLog()/log upload actually retain), see the logging guide.

All six subscriptions are cancelled together in dispose() via removeListeners(), and a headless task is registered once at startup — see Boot & killed-app behavior: Android headless tasks for what that task can and can’t do.

The example app's Map screen on iOS and Android: the status chip (linked, stationary, battery, point count), Start/Stop and Get position buttons, the tracked route drawn as a polyline, and the collapsed Collected coordinates sheet.

Connecting to the BGeo web console

The example app has no built-in “link device” screen — unlike the React Native example’s Settings-tab linking flow, wiring this app up to the web console means calling setConfig() yourself with the url, logUrl, and authorization values a registration-code exchange returns. See the web console guide’s linking section for the exact request/response shape and the equivalent Dart snippet.

The example app's Settings screen on iOS and Android: the Debug console linking panel, the Appearance theme picker, and the Geolocation config section with desired accuracy, distance filter, stationary radius, and keep-alive controls.