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".
Updated about 1 year ago