Skip to content

AppConfig

class AppConfig

Application and lifecycle configuration for the background geolocation SDK.

AppConfig controls how the SDK integrates with your app's lifecycle: tracking behavior on terminate and reboot, headless operation, periodic heartbeats, automated scheduler windows, foreground notifications, and the Android background-permission rationale dialog.

Contents

Overview
Category Properties Notes
Lifecycle stopOnTerminate, startOnBoot Controls tracking across app terminate and device reboot.
Headless enableHeadless Android only Tracking continues with no JS/UI process.
Heartbeat heartbeatInterval, preventSuspend Periodic background callbacks. preventSuspend is iOS only.
Scheduler schedule, scheduleUseAlarmManager Automated start/stop windows. scheduleUseAlarmManager is Android only.
Notification notification Android only Foreground service notification.
Permission backgroundPermissionRationale Android only Android 11+ background location rationale.
BackgroundGeolocation.ready(Config(
  app: AppConfig(
    stopOnTerminate: false,
    startOnBoot: true
  )
));

Lifecycle

AppConfig.stopOnTerminate (default true) controls whether tracking stops when the user terminates the app. Set to false to continue tracking after termination — iOS and Android handle this differently:

  • iOS creates a stationary geofence and relaunches the app when the device exits it (~200 m). Tracking resumes automatically.
  • Android continues the native background service headlessly. Pair with HttpConfig.url to ensure uploads continue without the UI layer.

AppConfig.startOnBoot (default false) controls whether tracking resumes after a device reboot. On Android, the background service restarts automatically. On iOS, the OS must first wake the app via a stationary geofence exit or a Background Fetch event.

AppConfig.enableHeadless (default false) allows Android to respond to SDK events even after the app is terminated. Requires stopOnTerminate: false. Android only


Heartbeat

AppConfig.heartbeatInterval fires BackgroundGeolocation.onHeartbeat periodically while the app is in the background. On iOS, this requires AppConfig.preventSuspend true to keep the app alive. On Android, the minimum interval is 60 seconds.

AppConfig.preventSuspend (default false) prevents iOS from suspending the app when location services are inactive. Required for heartbeat support on iOS but increases battery consumption — use only for specific, time-limited use cases. iOS only


Scheduler

AppConfig.schedule accepts an array of schedule strings that tell the SDK when to automatically start and stop tracking. Each string follows the format "DAY(s) HH:mm-HH:mm" using 24h time and Locale.US day numbers (Sunday=1, Saturday=7).

Call BackgroundGeolocation.startSchedule to activate the scheduler after calling ready().

AppConfig.scheduleUseAlarmManager (default false) forces the Android scheduler to use AlarmManager (exact, on-the-minute) instead of JobScheduler (inexact). Android only


Background permission

Android 11 removed the Allow all the time option from the system location dialog. Configure AppConfig.backgroundPermissionRationale to show a custom rationale dialog that routes the user to the system Location Permissions screen to grant background access. The SDK shows this dialog automatically when GeoConfig.locationAuthorizationRequest is "Always". Android only

See PermissionRationale for the full dialog configuration reference.


Examples
await BackgroundGeolocation.ready(Config(
  app: AppConfig(
    stopOnTerminate: false,
    startOnBoot: true,
    enableHeadless: true,
    heartbeatInterval: 60.0,
    backgroundPermissionRationale: PermissionRationale(
      title: "Allow MyApp to access this device's location even when closed.",
      message: "This app collects location data to record your trips and mileage.",
      positiveAction: 'Change to "{backgroundPermissionOptionLabel}"',
      negativeAction: 'Cancel'
    ),
    notification: Notification(
      title: 'Background Geolocation',
      text: 'Tracking location',
      smallIcon: 'mipmap/ic_launcher'
    ),
    schedule: ['1-5 09:00-17:00'], // Weekdays 9–5
    scheduleUseAlarmManager: true
  )
));
await BackgroundGeolocation.setConfig(Config(
  app: AppConfig(
    heartbeatInterval: 120.0 // slow down heartbeats
  )
));
Configure once at startup:
await BackgroundGeolocation.ready(Config(
  app: AppConfig(
    stopOnTerminate: false,
    startOnBoot: true,
    enableHeadless: true,
    heartbeatInterval: 60.0,
    backgroundPermissionRationale: PermissionRationale(
      title: "Allow MyApp to access this device's location even when closed.",
      message: "This app collects location data to record your trips and mileage.",
      positiveAction: 'Change to "{backgroundPermissionOptionLabel}"',
      negativeAction: 'Cancel'
    ),
    notification: Notification(
      title: 'Background Geolocation',
      text: 'Tracking location',
      smallIcon: 'mipmap/ic_launcher'
    ),
    schedule: ['1-5 09:00-17:00'], // Weekdays 9–5
    scheduleUseAlarmManager: true
  )
));
Update later at runtime:
await BackgroundGeolocation.setConfig(Config(
  app: AppConfig(
    heartbeatInterval: 120.0 // slow down heartbeats
  )
));

Members

backgroundPermissionRationale

PermissionRationale? backgroundPermissionRationale

Android only Configures the dialog shown when requesting Always background location permission on Android 11 and later.

Android 11 removed the Allow all the time button from the system permission dialog. Apps may instead present a custom rationale dialog explaining why background access is required. Selecting the dialog's positiveAction sends the user directly to the system Location Permissions screen, where they must enable Allow all the time.

The SDK shows this dialog automatically when AppConfig.backgroundPermissionRationale is configured and GeoConfig.locationAuthorizationRequest is "Always".

  • The rationale dialog is shown once only. After the user presses the positiveAction, it will not appear again. Pressing Cancel does not count.
  • If the user later resets your app's Location permission to Ask every time, the dialog may be presented again.

BackgroundGeolocation.ready(Config(
  geolocation: GeoConfig(
    locationAuthorizationRequest: 'Always'
  ),
  app: AppConfig(
    backgroundPermissionRationale: PermissionRationale(
      title: "Allow {applicationName} to access this device's location in the background?",
      message: "To track your activity in the background, please enable {backgroundPermissionOptionLabel} location permission.",
      positiveAction: "Change to {backgroundPermissionOptionLabel}",
      negativeAction: "Cancel"
    )
  )
));
Template tags

Embed the following variables inside PermissionRationale fields using {tagName} syntax:

Template Tag Default value Description
{backgroundPermissionOptionLabel} Allow all the time Localized label for the background permission option (API 30+).
{applicationName} Your app name From AndroidManifest.xml.

See also - GeoConfig.locationAuthorizationRequest - BackgroundGeolocation.requestPermission - Location updates in Android 11

enableHeadless

bool? enableHeadless

Android only Enables headless operation so the SDK can respond to events after the app has been terminated with AppConfig.stopOnTerminate false. Defaults to false.

In the headless state only the native foreground service is running — the JS/UI process is gone. Register a callback with BackgroundGeolocation.registerHeadlessTask to handle events in this state.

Note

  • Requires AppConfig.stopOnTerminate false.
  • With stopOnTerminate: false, the SDK records and uploads locations regardless of enableHeadless. Enable this only if you need to perform custom work during the headless state (for example, posting a local notification).

See also - Android Headless Mode - BackgroundGeolocation.registerHeadlessTask

heartbeatInterval

int? heartbeatInterval

Rate in seconds at which BackgroundGeolocation.onHeartbeat events fire while the app is in the background.

iOS

Requires AppConfig.preventSuspend true. Defaults to 60 seconds when enabled.

Android

Heartbeat is disabled by default (-1). Set to a positive integer of at least 60 to enable it. Values below 60 are not supported.

Warning

  • On iOS, heartbeat fires only when AppConfig.preventSuspend is true.
  • On Android, the minimum supported interval is 60 seconds.

See also - BackgroundGeolocation.onHeartbeat

BackgroundGeolocation.ready(Config(
  app: AppConfig(
    preventSuspend: true,
    heartbeatInterval: 60.0
  )
));

BackgroundGeolocation.onHeartbeat((HeartbeatEvent event) {
  print('[onHeartbeat] ${event}');

  // Optionally request a new location during heartbeat.
  BackgroundGeolocation.getCurrentPosition({
    samples: 1,
    persist: true
  }).then((location) {
    print('[getCurrentPosition] ${location}');
  });
});

notification

Notification? notification

Android only Configures the persistent foreground-service notification required by Android.

See NotificationConfig for detailed usage.

BackgroundGeolocation.ready(Config(
  app: AppConfig(
    notification: Notification(
      title: "Background tracking engaged",
      text: "My notification text"
    )
  )
));

preventSuspend

bool? preventSuspend

iOS only Prevents iOS from suspending the application after location services have been disabled while running in the background. Defaults to false. Set to true to keep the app alive in the background even after iOS disables location services. This is required for AppConfig.heartbeatInterval to fire on iOS.

Warning

preventSuspend: true has a large and noticeable impact on battery consumption. Use it only for specific, time-limited use cases — it is not suitable for continuous 24/7 operation.

When the device is unplugged with the screen off, iOS still throttles heartbeat events approximately 2 minutes after entering the background. Heartbeats resume immediately when the screen turns on or any device motion is detected.

See also - AppConfig.heartbeatInterval - BackgroundGeolocation.onHeartbeat

// Subscribe to heartbeat events
BackgroundGeolocation.onHeartbeat((HeartbeatEvent event) {
  print('[onHeartbeat] ${event}');
});

// Enable preventSuspend via AppConfig
BackgroundGeolocation.ready(Config(
  app: AppConfig(
    preventSuspend: true,
    heartbeatInterval: 60.0,
  )
));

schedule

List<String>? schedule

Configures a cron-like automated schedule that tells the SDK when to start and stop tracking.

"{DAY(s)} {START_TIME}-{END_TIME}"
  • Times are in 24h format.
  • DAY uses Locale.US day numbers: Sunday = 1, Saturday = 7.
  • Day values may be a single day ("1"), a comma-separated list ("2,4,6"), or a range ("2-6").
BackgroundGeolocation.ready(Config(
  app: AppConfig(
    schedule: [
      "1 17:30-21:00",     // Sunday: 5:30pm–9pm
      "2-6 09:00-17:00",   // Mon–Fri: 9am–5pm
      "2,4,6 20:00-00:00", // Mon, Wed, Fri: 8pm–midnight
      "7 10:00-19:00"      // Saturday: 10am–7pm
    ]
  )
)).then((state) {
  // Start the Scheduler
  BackgroundGeolocation.startSchedule();
});

// Listen for schedule state changes
BackgroundGeolocation.onSchedule((State state) {
  print('[onSchedule] enabled? ${state.enabled}');
});

// Later (e.g., user logout)
BackgroundGeolocation.stopSchedule();
BackgroundGeolocation.stop(); // if tracking is currently active

// Modify schedule using setConfig
BackgroundGeolocation.setConfig(Config(
  app: AppConfig(
    schedule: [
      "1-7 09:00-10:00",
      "1-7 11:00-12:00",
      "1-7 13:00-14:00",
      "1-7 15:00-16:00",
      "1-7 17:00-18:00",
      "2,4,6 19:00-22:00"
    ]
  )
));
Literal dates

A schedule entry may use a literal date range:

"yyyy-mm-dd HH:mm-HH:mm"
BackgroundGeolocation.ready(Config(
  app: AppConfig(
    schedule: [
      "2018-01-01 09:00-17:00"
    ]
  )
));

Or specify distinct start and stop dates:

"yyyy-mm-dd-HH:mm yyyy-mm-dd-HH:mm"
BackgroundGeolocation.ready(Config(
  app: AppConfig(
    schedule: [
      "2018-01-01-09:00 2019-01-01-17:00" // track for 1 year
    ]
  )
));
Scheduling modes

Append geofence or location to explicitly choose a tracking mode.

BackgroundGeolocation.ready(Config(
  app: AppConfig(
    schedule: [
      "1-7 09:00-17:00 location",
      "1-7 18:00-00:00 geofence"
    ]
  )
));
iOS
  • iOS cannot evaluate the schedule exactly at the configured time. Evaluation occurs only when the app is awakened.
  • During a scheduled off period, iOS continues monitoring low-power Significant Location Changes (SLC) to guarantee periodic re-evaluation, especially when AppConfig.stopOnTerminate is false and the OS halts traditional Background Fetch.
  • Schedule evaluation occurs when the app pauses/resumes, any location is recorded (including SLC), or a Background Fetch event fires.
Android

Uses AlarmManager.setExactAndAllowWhileIdle, typically evaluating on-the-minute.

See also - BackgroundGeolocation.startSchedule - BackgroundGeolocation.stopSchedule

Since location is the default mode, it may be omitted
BackgroundGeolocation.ready(Config(
  app: AppConfig(
    schedule: [
      "1-7 09:00-17:00 location",
      "1-7 18:00-12:00 geofence"
    ]
  )
));

scheduleUseAlarmManager

bool? scheduleUseAlarmManager

Android only Forces the Android scheduler to use AlarmManager (exact, on-the-minute) instead of JobScheduler (inexact). Defaults to false.

BackgroundGeolocation.ready(Config(
  app: AppConfig(
    schedule: ["1-7 09:00-17:00"],
    scheduleUseAlarmManager: true
  )
));

startOnBoot

bool? startOnBoot

Controls whether tracking resumes automatically after the device reboots. Defaults to false.

iOS

iOS cannot begin tracking immediately after a reboot. Similar to AppConfig.stopOnTerminate false, the SDK waits until one of the following occurs: - The device exits the stationary geofence created around the last known location. - A system Background Fetch event fires (typically every ~15 minutes).

Android

When true, Android relaunches the SDK background service after reboot and initial device unlock. If AppConfig.enableHeadless is also true, tracking resumes even before the JS/UI layer starts.

See also - AppConfig.enableHeadless - AppConfig.stopOnTerminate

stopOnTerminate

bool? stopOnTerminate

Controls whether tracking stops when the application is terminated by the user. Defaults to true.

When true, the SDK calls stop() as the app terminates. Set to false to keep tracking alive after termination — iOS and Android behave differently in this state.

iOS

Before termination, the SDK registers a stationary geofence of GeoConfig.stationaryRadius meters around the last known position. When the device exits that geofence (~200 m), iOS fully relaunches the app in the background and tracking resumes automatically. This mechanism survives device reboot because iOS monitors geofences at the OS level.

Demo video: https://www.youtube.com/watch?v=aR6r8qV1TI8&t=214s

Android

Android does not pause tracking when the user terminates the app. The native background service continues running headlessly without the JS/UI process. Configure HttpConfig.url so the service can continue uploading locations to your server.

See also - AppConfig.enableHeadless - Android Headless Mode