Android – Location Permission & Notifications Best Practices

Location permissions

Prior to starting any Bluedot Services (Geo-triggering or Tempo), the app must request and be granted location permission, specifically ACCESS_FINE_LOCATION. If the app has not been granted permission to access location data the Geo-triggering and Tempo services will not start, and the start method will return a LocationPermissionNotGrantedError. To ensure the location permission has been granted, it is important to implement the checking and requesting process prior to any attempt to start a Bluedot service. When requesting location permission it is important to make the request in context and convey the value the user will be gaining from granting the permission.

Additionally, from Android 10 onwards, if the Geo-triggering service is not run as a foreground service, the ACCESS_BACKGROUND_LOCATION permission must be requested and granted in order for the Geo-triggering service to access location data and function when the app is not in use. From Android 11 onwards, the request to access background location data must be made separately from the initial request to access location data. Even when granted permission to access background location data the access is limited to only a few updates per hour while the app is not in use. The Play Store also has restrictions on how apps published on the store may utilise background location data.

Foreground service and persistent notification

Given the restrictions on accessing location data from the background, it is recommended that the Geo-triggering service be run as a foreground service, and the Tempo service must be run as a foreground service. Implementing a foreground service is the best practice for ensuring users are fully aware of how and when their location is accessed and also for the most efficient use of system resources. When a foreground service is running, there will be a persistent notification in the notification tray informing the user that your app is accessing the device location when the app is in the foreground and background.

To run as a foreground service the GeoTriggerBuilder and TempoBuilder must be passed a Notification via the notification() method. This is the notification that will be displayed persistently as long as the service is running. The notification should convey to the user why the app is collecting location data, and what value they are receiving from allowing the app to do so.

Please see our Minimal Integration project for examples on how to build notifications and start Geo-triggering and Tempo as foreground services.

If a notification is passed in during Geo-triggering or Tempo initialization, the notification will be displayed across all device OS versions.  To only display the notification on devices running Android Oreo and above, where it is required to access location data from the background, perform a version check when initializing the service and pass in notification only if the OS version is API level 26 or above:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    GeoTriggeringService.builder()
            .notification(notification)
            .start(this, geoTriggerError -> {
                // Call method to handle Geo-triggering initialization here.
            });
} else {
    GeoTriggeringService.builder()
            .start(this, geoTriggerError -> {
                // Call method to handle Geo-triggering initialization here.
            });
}

If your app runs another foreground service or will run the Geo-triggering service and Tempo service simultaneously, it is best practice to use the same notification ID. Using the same notification ID ensures that only a single persistent notification will be displayed for all running foreground services. The GeoTriggerBuilder and TempoBuilder expose notificationId() methods to set the notification ID, and the GeoTriggeringService and TempoService expose the notification ID in use via foregroundNotificationId() methods. The notification ID may be used to update the notification after starting a service. Be aware that the most recent notification used to start a service, or the last update, will be displayed as long as any foreground service is running, thus it may be necessary to update the notification when stopping service to ensure the content remains correct.

Created by Melwin Chiramel on December 22, 2020