Product

Navigating location services tradeoffs between accuracy, frequency, and battery efficiency

by

Nick Patrick

on

February 26, 2020

When a Dungeons & Dragons player creates a character, they distribute points to attributes including strength, dexterity, and wisdom.

These choices involve tradeoffs. With a limited number of points to distribute, a higher strength score may mean a lower wisdom score, and vice versa. The right balance may differ depending on the campaign.

stranger

Building with location services also requires choices that involve tradeoffs. But instead of trading off strength, dexterity, and wisdom, a developer must trade off accuracy, frequency, and battery efficiency instead.

template

Why is that? iOS and Android location services use a combination of GPS, wi-fi scanning, and cell tower triangulation to determine a device's location.

  • GPS is accurate down to a few meters outdoors, but with the highest battery drain.
  • Wi-fi scanning is accurate down to a few dozen meters, with medium battery drain.
  • Cell tower triangulation is accurate only to a few thousand meters, but with the lowest battery drain.

If I request a higher accuracy (e.g., kCLLocationAccuracyBest on iOS or PRIORITY_HIGH_ACCURACY on Android), location services may switch to GPS, draining more battery.

Or, if I request a higher frequency (e.g., an interval of 30 seconds instead of 60 seconds on Android), location services will power up more often, again draining more battery.

A "perfect" location services implementation (perfect accuracy, real-time updates, and zero battery drain) is unfortunately not possible. Instead, a developer must choose a balance of accuracy, frequency, and efficiency that makes sense depending on use case.


Fortunately, Radar SDK v3 introduces new tracking options and presets to help you choose the right balance of accuracy, frequency, and efficiency for your use case.

Presets include:

  • EFFICIENT, with a low frequency of location updates and lowest battery usage. On Android, avoids Android vitals bad behavior thresholds.
  • RESPONSIVE, with a medium frequency of location updates and low battery usage.
  • CONTINUOUS, with a high frequency of location updates and higher battery usage.

If we were distributing points to accuracy, frequency, and efficiency, the presets might look like this:

presets h

The CONTINUOUS preset is suitable for on-demand use cases (e.g., delivery tracking) and some consumer use cases (e.g., order ahead).

The EFFICIENT and RESPONSIVE presets are suitable for most consumer use cases.

You might also toggle between presets.


For example, an on-demand app may start CONTINUOUS tracking when a delivery starts, then stop tracking when the delivery is complete:

// delivery started
Radar.startTracking(RadarTrackingOptions.continuous)

...

// called on every location update
func didUpdateLocation(_ location: CLLocation, user: RadarUser) {
  if !isDeliveryInProgress {
    Radar.stopTracking()
  }
}

Or, a travel app may start RESPONSIVE tracking during a trip, then toggle to EFFICIENT tracking when the trip is complete:

// trip started
Radar.startTracking(RadarTrackingOptions.responsive)

...

// called on every location update
func didUpdateLocation(_ location: CLLocation, user: RadarUser) {
  if !isOnTrip {
    Radar.startTracking(RadarTrackingOptions.efficient)
  }
}

Finally, a shopping app may start CONTINUOUS tracking while inside of a mall geofence, then toggle to EFFICIENT tracking outside of a mall:

Radar.startTracking(RadarTrackingOptions.efficient)

...

// called on every location update
func didUpdateLocation(_ location: CLLocation, user: RadarUser) {
  let isAtMall = user?.geofences?.contains { geofence in
    geofence.tag == "mall"
  } ?? false

  if isAtMall {
    Radar.startTracking(RadarTrackingOptions.continuous)
  } else {
    Radar.startTracking(RadarTrackingOptions.efficient)
  }
}

Though we recommend using presets for most use cases, you can modify them.

The SDK has two states: stopped and moving. stopDuration and stopDistance determine whether a location update is considered stopped, and the other options determine tracking behavior depending on state. Frequency, accuracy, and other options are configurable:

// presets
Radar.startTracking(RadarTrackingOptions.efficient)
Radar.startTracking(RadarTrackingOptions.responsive)
Radar.startTracking(RadarTrackingOptions.continuous)

// custom
let trackingOptions = RadarTrackingOptions.continuous
trackingOptions.desiredMovingUpdateInterval = 60
trackingOptions.desiredStoppedUpdateInterval = 180
trackingOptions.desiredAccuracy = .high
trackingOptions.stopDuration = 50
trackingOptions.stopDistance = 30
trackingOptions.stopTrackingAfter = date
trackingOptions.sync = .all
Radar.startTracking(trackingOptions)

Just keep in mind the tradeoffs above!


Radar can't help you with D&D character creation, but we can help you build amazing location-aware app experiences.

New to Radar? Sign up, then check out the SDK documentation to get started.

Want to stay in the loop about location services best practices? Subscribe to the newsletter below.

Happy coding!

It's time to build

See what Radar’s location and geofencingsolutions can do for your business.