This section describes some typical location-gathering scenarios, along with recommendations for optimal use of the geofencing and fused location provider APIs.
User visible or foreground updates
Example: A mapping app that needs frequent, accurate updates with very low latency. All updates happen in the foreground: the user starts an activity, consumes location data, and then stops the activity after a short time.
Use the setPriority()
method with a value of
PRIORITY_HIGH_ACCURACY
or PRIORITY_BALANCED_POWER_ACCURACY
.
The interval specified in the setInterval()
method depends on the use
case: for real time scenarios, set the value to few seconds; otherwise, limit to
a few minutes (approximately two minutes or greater is recommended to minimize
battery usage).
Know the location of the device
Example: A weather app wants to know the device's location.
Use the getLastLocation()
method, which returns the most recently
available location (which in rare cases may be null). This method provides a
straightforward way of getting location and doesn't incur costs associated with
actively requesting location updates. Use in conjunction with the
isLocationAvailable()
method, which returns true
when the location
returned by getLastLocation()
is reasonably up-to-date.
Start updates when a user is at a specific location
Example: Requesting updates when a user is within a certain distance of work, home, or another location.
Use geofencing in conjunction with fused location provider updates. Request updates when the app receives a geofence entrance trigger, and remove updates when the app receives a geofence exit trigger. This ensures that the app gets more granular location updates only when the user has entered a defined area.
The typical workflow for this scenario could involve surfacing a notification upon the geofence enter transition, and launching an activity which contains code to request updates when the user taps the notification.
Start updates based on the user's activity state
Example: Requesting updates only when the user is driving or riding a bike.
Use the Activity Recognition API in conjunction with fused location provider updates. Request updates when the targeted activity is detected, and remove updates when the user stops performing that activity.
The typical workflow for this use case could involve surfacing a notification for the detected activity, and launching an activity which contains code to request updates when the user taps the notification.
Long running background location updates tied to geographical areas
Example: The user wants to be notified when the device is within proximity of a retailer.
This is an excellent use case for geofencing. Because the use case almost
certainly involves background location, use the
addGeofences(GeofencingRequest, PendingIntent)
method.
You should set the following configuration options:
If you're tracking dwell transitions, use the
setLoiteringDelay()
method passing a value of approximately five minutes or less.Use the
setNotificationResponsiveness()
, passing a value of approximately five minutes. However, consider using a value of approximately ten minutes if your app can manage the extra delay in responsiveness.
An app may only register a maximum of 100 geofences at a time. In a use case where an app wants to track a large number of retailer options, the app may want to register large geofence (at the city level) and dynamically register smaller geofences (for locations within the city) for stores within the larger geofence. When a user enters a large geofence, add smaller geofences; when the user exits the larger geofence, remove the smaller geofences and re-register geofences for a new area.
Long running background location updates without a visible app component
Example: An app that passively tracks location
Use the setPriority()
method with the PRIORITY_NO_POWER
option if
possible because it incurs almost no battery drain. If using PRIORITY_NO_POWER
isn't possible, use PRIORITY_BALANCED_POWER_ACCURACY
or
PRIORITY_LOW_POWER
, but avoid using PRIORITY_HIGH_ACCURACY
for
sustained background work because this option substantially drains battery.
If you need more location data, use passive location by calling the
setFastestInterval()
method passing a smaller value than what you pass
to setInterval()
. When combined with the PRIORITY_NO_POWER
option, passive location can opportunistically deliver location computed by
other apps at no extra cost.
Moderate frequency by adding some latency, using the setMaxWaitTime()
method. For example, if you use the setinterval()
method with a value of
approximately 10 minutes, you should consider calling setMaxWaitTime()
with a
value between 30 to 60 minutes. Using these options, location is computed for
your app approximately every 10 minutes, but the app is only woken up every 30
to 60 minutes with some location data available as a batch update. This approach
trades latency for more data available and better battery performance.
Frequent high accuracy updates while the user interacts with other apps
Example: A navigation or fitness app that continues to work when the user either turns off the screen or opens a different app.
Use a foreground service. If expensive work is potentially going to be done by your app on behalf of the user, making the user aware of that work is a recommended best practice. A foreground service requires a persistent notification. For more information, see Notifications Overview.