Android: Location Updates

A guide to location updates on the Android platform

Android location updates can be requested using the FusedLocationProviderClient class. You will need to add the play services location library to your app.

implementation "com.google.android.gms:play-services-location:16.0.0"

Location Permissions

In order to receive location updates you will need to have the correct permissions. These should be added to the AndroidManifest.xml for your app.

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

These permissions are not granted automatically and will also need to be requested while your app is running. You can check and request permissions like so:

if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    int requestCode = 123; // Define your request code

    // request permissions
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, requestCode);
}
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.ACCESS_FINE_LOCATION) !== PackageManager.PERMISSION_GRANTED) {
    val requestCode = 123 // Define your request code

    // request permissions
    ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), requestCode)
}

Requesting permissions will show a popup to the user asking for their permission to use location services. It is recommended to first introduce locations to the user within the app and explain why you are using them before showing the permissions popup.

Requesting Location Updates

Once you have received permission, the calling activity will be informed of the result in the onRequestPermissionsResult method. You can now register for location updates. One option for receiving these is in a BroadcastReceiver. We will be using this method for our guide.

First you should create the BroadcastReceiver:

public class LocationBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            new Marigold().updateLocation(location);
        }
    }
}
class LocationBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (LocationResult.hasResult(intent)) {
            val locationResult: LocationResult = LocationResult.extractResult(intent)
            val location: Location = locationResult.lastLocation
            SailthruMobile().updateLocation(location)
        }
    }
}

This will pass the location to Marigold using the updateLocation method when it is received. You should then add the LocationBroadcastReceiver to the manifest.

<receiver android:name=".LocationBroadcastReceiver"
          android:exported="false"/>

You can then request location updates to this receiver through the FusedLocationProviderClient (once you have permission).

// setup intent for BroadcastReceiver
Intent locationServiceIntent = new Intent(this, LocationBroadcastReceiver.class);

// create pending intent for location services
PendingIntent locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);

// get FusedLocationProviderClient
FusedLocationProviderClient locationProviderClient = LocationServices.getFusedLocationProviderClient(this);

// setup location request
long locationUpdateInterval = 180000; // update interval in milliseconds
long locationMaxUpdateInterval = 300000; // max update interval in milliseconds

LocationRequest locationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(locationUpdateInterval).setMaxWaitTime(locationMaxUpdateInterval);

// request updates
locationProviderClient.requestLocationUpdates(locationRequest, locationIntent);
// setup intent for BroadcastReceiver
val locationServiceIntent = Intent(this, LocationBroadcastReceiver::class.java)

// create pending intent for location services
val locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT)

// get FusedLocationProviderClient
val locationProviderClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

// setup location request
val locationUpdateInterval: Long = 180000 // update interval in milliseconds

val locationMaxUpdateInterval: Long = 300000 // max update interval in milliseconds


val locationRequest: LocationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(locationUpdateInterval).setMaxWaitTime(locationMaxUpdateInterval)

// request updates
locationProviderClient.requestLocationUpdates(locationRequest, locationIntent)

The broadcast receiver will receive updates until the updates are removed:

// setup intent for BroadcastReceiver
Intent locationServiceIntent = new Intent(this, LocationBroadcastReceiver.class);

// create pending intent for location services
PendingIntent locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);

// remove location updates
locationProviderClient.removeLocationUpdates(locationIntent);
// setup intent for BroadcastReceiver
val locationServiceIntent = Intent(this, LocationBroadcastReceiver::class.java)

// create pending intent for location services
val locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT)

// remove location updates
locationProviderClient.removeLocationUpdates(locationIntent)

📘

Note

Android throttles location updates for apps that are in the background or terminated to "a few updates per hour".