Skill Level: Any

With Android 8, Google introduced background location limits. These have been extended in Android 9. They are intended to allow batteries to last longer than they did on Android 7.1.1. This is accomplished by turning off location services and then turning them on for only brief periods. The result of this Android change is that when your app is in the background, geofences and beacons may be detected irregularly, with significant delays. Our testing revealed at least one case where it took 30 minutes for a geofence to be detected. This can pose a challenge for developers who want to react to location opportunities more quickly. As shipped, the Android SDK attempts to work around background location limits, but is constrained by the OS. Google has provided a few options to keep apps in the foreground and make location detection faster. Some of them, such as installing a Wallpaper or multiple apps, are not likely to be acceptable to users. The most promising solution appears to be to start a foreground service when your app enters the background, and then to terminate that service when your app comes back into the foreground. This has a minor disadvantage: Android will display your app's icon in the notification bar. This is an Android feature intended to let the device user know that your app is running; there is no way to disable this indication. We've implemented the foreground solution below. Use the instructions below to add the appropriate code to your app. This will ensure that geofences and beacons are detected quickly.


Find out more from Google about background location limits.


Not what you’re looking for? Check out all our available tutorials for mobile app messaging here.


  1. Start a foreground process when your app enters background mode

    To prevent your app from being unresponsive to a geofence, or a beacon enter/exit event, you can start a foreground process whenever the app enters background mode. This stops the process when the app comes to the foreground. This has the side-effect of leaving a visual indicator that your app is running in the status bar.

    Detection of the application state change is typically handled by a class that implements Application.ActivityLifecycleCallbacks. An example which works with the sample app can be found in ApplicationLifecycleHandler.java.

    (attach ApplicationLifecycleHandler.java so that it’s downloadable)

  2. Register the lifecycle handler in the application

    The lifecycle handler must be registered in the application. This can be done by adding the following code to the end of the onCreate method:

    ApplicationLifecycleHandler handler = new ApplicationLifecycleHandler();
  3. Add the NotificationChannel

    The foreground service will need its own NotificationChannel, which should be added to the end of createNotificationChannel():

    // create a separate notification channel for the service notification
    NotificationChannel serviceChannel = notificationManager.getNotificationChannel(MCE_SERVICE_CHANNEL_ID);
    if(serviceChannel == null) {
    CharSequence name = "WCA SDK Service Channel";
    String description = "This keeps the app alive for geofence detection";
    int importance = NotificationManager.IMPORTANCE_LOW;
    serviceChannel = new NotificationChannel(MCE_SERVICE_CHANNEL_ID, name, importance);
  4. Add a foreground service

    Next, add a foreground service itself:

    (attach ForegroundService.java so that it’s downloadable)



  5. Update the AndroidManifest.xml

    Finally, you’ll need to update the AndroidManifest.xml to give appropriate permissions to the ForegroundService:

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  6. New and modified files for the sample app

    A zip file containing all new and modified files appropriate for the sample app can be found in the release or at:


Expected outcome

Need more help? Check out all of our available tutorials for mobile app messaging here.

Join The Discussion

Your email address will not be published. Required fields are marked *