That is a common practice when a developer needs to get the device’s coordinates. Fortunately, all modern smartphones, regardless of the platform they run on, have built-in tools for this purpose. 

In this article, we will talk about dealing with geolocations in the Android OS. Let’s first of all point out the main methods of location tracking.

GPS

Nowadays, this method allows us to track location with the highest possible accuracy. Some drawbacks it has are as follows: high energy consumption, impossibility to track location indoors, troubles finding satellites.

Wi-Fi Networks

This method allows getting coordinates of the device quite fast. It uses the Wi-Fi network's databases for this purpose. The need to use this method arises mostly indoors. Tracking location with the help of Wi-Fi networks doesn’t influence energy consumption. The main drawback is that Wi-Fi networks are not available everywhere.

Mobile Networks

They are much more widespread than Wi-Fi networks. But the return coordinates have significantly lower accuracy than the previous method. This is due to the fact that the distance to the nearest cell tower can sometimes reach tens of kilometers.

Android OS offers several methods of current location tracking. Before starting, one has to add the permission to AndroidManifest to access the geolocation.

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

This permission allows us to work with both GPS and network coordinate providers.  When we only need the ability to work with network providers, we can use ACCESSCOARSELOCATION.

  • LocationManager. It allows us to control the work with geopositions, setting such parameters as the used provider type (GPS, networks), accuracy, speed, frequency etc. To get the instance of this class, you need to call
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
view raw LocationManager.java hosted with ❤ by GitHub

To sign up for the notifications about the changes in location, we need to define LocationListener and send it as a parameter to the requestLocationUpdates method:

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
doSomethingWithLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

In this example, LocationManager is subscribed to get notifications about the location changes only from the Wi-Fi networks and cell towers (but we can as well request GPS usage). The second parameter of the requestLocationUpdates method is intended to control the update timeframe, the third one - to control the distance. The fourth parameter is a callback, getting notifications. In this case, the notifications will be received as often as possible. But it is recommended to expand the second and the third parameter within the allowed measurement accuracy to save the battery charge.

The method described above allows us to get the coordinates both immediately and within a few minutes. This can be unacceptable when we need to track the user’s location very fast. That is why we can get the last coordinates the system knows. This can be done in the following way:

String locationProvider = LocationManager.NETWORK_PROVIDER;
// Or LocationManager.GPS_PROVIDER
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);

Judging from our own experience when using this method, we can say that sometimes really old (and outdated) information about the coordinates or even null can be returned. It can occur if geolocation on the user’s device has been off for some time or if it hasn’t been enabled at all.

  • Google Play Services. The process of including this library is described here. It gives lots of opportunities, but it is impossible to list all of them in this article. Its main feature is that this library can track location by itself or on request of an app and allows to get the coordinates very fast.

In one of the last versions of the Google Play Services library LocationClient class is marked as deprecated. It is recommended to use GoogleApiClient instead of it. This class allows working with many Google services (not only geolocation). Now to get the coordinates, we need to make 2 other callbacks:

GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener

After doing so we need to use GoogleApiClient object’s builder:

GoogleApiClient googleApiClient = new GoogleApiClient.Builder(Context)
.addConnectionCallbacks(GoogleApiClient.ConnectionCallbacks)
.addOnConnectionFailedListener(
GoogleApiClient.OnConnectionFailedListener)
.addApi(LocationServices.API)
.build()
view raw GoogleApiClient.java hosted with ❤ by GitHub

In the onStart() method of Activity class we call GoogleApiClient.connect(). In onStop() method we call GoogleApiClient.disconnect() (to save the battery life), if GoogleApiClient.isConnected() returns true.

After the callback onConnected(Bundle bundle) is called, we can get the last coordinates - LocationServices.FusedLocationApi.getLastLocation(GoogleApiClient). From our own experience, we can tell that usually, the most up-to-date coordinates are the ones that are returned. In the case null returns (which happens quite rarely), we can request the coordinates update with the help of LocationServices.FusedLocationApi.requestLocationUpdates method. We have to pass the LocationRequest object (it allows to set up update parameters, such as frequency of updates, accuracy etc.) and LocationListener to it. As soon as we get the coordinates (it usually takes 1-2 seconds) the callback onLocationChanged(Location location) will be called.

public class LocationActivity extends FragmentActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener{
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
mLocationRequest = LocationRequest.create();
/*
* Set the update interval
*/
mLocationRequest.setInterval(300000);
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the interval ceiling to one minute
mLocationRequest.setFastestInterval(180000);
mGoogleApiClient = new GoogleApiClient.Builder(Context)
.addConnectionCallbacks(GoogleApiClient.ConnectionCallbacks)
.addOnConnectionFailedListener(
GoogleApiClient.OnConnectionFailedListener)
.addApi(LocationServices.API)
.build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
@Override
public void onConnectionFailed(ConnectionResult arg0) {
// Handle this according to the logic of your app
}
@Override
public void onConnected(Bundle arg0) {
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (lastLocation == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onDisconnected() {}
@Override
public void onLocationChanged(Location location) {
// doSomethingWithNewLocation(location);
}
}

Provider Availability Check

Before trying to get the coordinates, we have to check if the geolocation is on and if there are any available providers. We offer the following method of doing this. The main idea is not to have to call LocationManager (its behavior has changed in Android version 4.3) directly but to use the access capability of the system parameters.

The tasks with geolocation occur quite often. In this regard, Android OS has a number of quite convenient tools we can use when working with coordinates. We recommend using Google Play Services instead of working with LocationManager directly. Trust us, it can save you a lot of efforts! Moreover, this library is preinstalled on all devices running on Android 2.2 and later and Google is actively developing and distributing it.

Want to learn more about our Android development services?

Get in touch with us to discuss your Android project and learn how our team can assist you.

Contact us