Android Example : Fetching Current Location with FusedLocationProviderAPI

Spread knowledge

marker

 

Fetching Location is one of the most useful features on mobile devices. In fact lot of apps completely rely on user’s location for their business, take Uber for example. This implies that it is very important to fetch user’s location accurately and seamlessly on mobile devices. In Android there are basically two methods to fetch user location

Android framework location APIs were the most reliable way of fetching location up until FusedLocationProviderApi was released. Fused location provider is found to be more accurate, fast and easy to implement. Above all Android doc itself encourages developers to migrate to Fused Location provider.

What is Fused Location Provider ?

The fused location provider is one of the location APIs in Google Play services. It manages the underlying location technology and provides a simple API so that you can specify requirements at a high level, like high accuracy or low power. It also optimizes the device’s use of battery power.It intelligently combines different signals (GPS, Wifi) to provide the location information that your app needs.

One of the most important advantage with Fused location provider is that unlike  Android’s Framework  Location Api, where you have to explicitly specify whether to fetch location using GPS or Network provider, it itself selects the source to  retrieve location based on the accuracy.  That is why its called “Fused”

Comple documentation of FusedLocationProviderApi is available here. The two most useful methods to fetch locations using FusedLocationProviderApi are

In the following example we will use the FusedLocationProviderAPI to fetch the current location and show in our app.

You will have much better understanding of FusedProvider once we go through the following example

If you are very new to Android development and are not familiar of how to Create your Hello Word Android App. Please read this

Step – 1

First you will have to add the following Google Play Services Location dependency to your build.gradle file

compile 'com.google.android.gms:play-services-location:11.0.2'

Step – 2
Add the following location permissions in your AndroidManifest.xml to inform  Android that your app will be fetching user location

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

Step-3
Create a activity by the name LocationActivity with a layout file activity_layout as shown below

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.androidclarified.locationapp.LocationActivity">
    <Button
        android:layout_width="wrap_content"
        android:text="Fetch Location"
        android:padding="10dp"
        android:layout_centerInParent="true"
        android:id="@+id/location_btn"
        android:layout_height="wrap_content" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:gravity="center"
        android:textSize="16sp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:layout_alignParentTop="true"
        android:id="@+id/location_text"/>
</RelativeLayout>

 

public class LocationActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {

 private Button locationButton;

 private TextView locationText;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_location);

  locationButton = (Button) findViewById(R.id.location_btn);
  locationText = (TextView) findViewById(R.id.location_text);

 }

}

We have a Button and TextView in our layout file. Whenever the button is clicked we will fetch the current location and show it in the TextView

Step-4

GoogleApiClient  is the main entry point for Google Play Services integration. This basically means that you will need a instance of GoogleApiClient in order to use Google Services APIs. Below code snippet creates a instance of Google API client and initiates the connection. It should also be noted that we have added the two listeners to the client to be notified of if the connection is successful or not. Our activity will be implementing the two interfaces and also override all the callback methods.

  • OnConnectionFailedListener :onConnectionFailed(ConnectionResult)
    Called when there was an error connecting the client to the service
  • ConnectionCallbacks 

    onConnected(Bundle)

    After calling connect(), this method will be invoked asynchronously when the connect request has successfully completed.

    onConnectionSuspended(int)

    Called when the client is temporarily in a disconnected state

public class LocationActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {

 private Button locationButton;

 private TextView locationText;

 //Initializing the GoogleApiClient object
 private GoogleApiClient googleApiClient;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_location);

  locationButton = (Button) findViewById(R.id.location_btn);
  locationText = (TextView) findViewById(R.id.location_text);

  //Building a instance of Google Api Client
  googleApiClient = new GoogleApiClient.Builder(this)
   .addApi(LocationServices.API)
   .addOnConnectionFailedListener(this)
   .addConnectionCallbacks(this)
   .build();
 }

 public void onStart() {
  super.onStart();
  // Initiating the GoogleApiClient Connection when the activity is visible
  googleApiClient.connect();
 }

 public void onStop() {
  super.onStop();
  //Disconnecting the GoogleApiClient when the activity goes invisible
  googleApiClient.disconnect();

 }

 /*
 This callback is invoked when the GoogleApiClient is successfully connected
 */
 @Override
 public void onConnected(@Nullable Bundle bundle) {
  //We set a listener to our button only when the ApiClient is connected successfully
  locationButton.setOnClickListener(this);
 }

 //Callback invoked if the GoogleApiClient connection is suspended
 @Override
 public void onConnectionSuspended(int i) {
  Toast.makeText(this, "Connection was suspended", Toast.LENGTH_SHORT);
 }

 //Callback invoked if the GoogleApiClient connection fails
 @Override
 public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
  Toast.makeText(this, "Connection failed", Toast.LENGTH_SHORT);
 }

 @Override
 public void onClick(View view) {
  switch (view.getId()) {
   case R.id.location_btn:
    break;

  }
 }
}

 

 

Step- 5

LocationServices is the main entry point for location service integration. We use it here to get the instance of FusedLocationProviderApi as shown below.

FusedLocationProviderApi fusedLocationApi = LocationServices.FusedLocationApi;

 

Our LocationActivity will finally look like this

public class LocationActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {

 private Button locationButton;

 private TextView locationText;

 //Initializing the GoogleApiClient object
 private GoogleApiClient googleApiClient;

 public static final int LOCATION_REQUEST = 101;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_location);

  locationButton = (Button) findViewById(R.id.location_btn);
  locationText = (TextView) findViewById(R.id.location_text);

  //Building a instance of Google Api Client
  googleApiClient = new GoogleApiClient.Builder(this)
   .addApi(LocationServices.API)
   .addOnConnectionFailedListener(this)
   .addConnectionCallbacks(this)
   .build();
 }

 public void onStart() {
  super.onStart();
  // Initiating the GoogleApiClient Connection when the activity is visible
  googleApiClient.connect();
 }

 public void onStop() {
  super.onStop();
  //Disconnecting the GoogleApiClient when the activity goes invisible
  googleApiClient.disconnect();

 }

 /*
 This callback is invoked when the GoogleApiClient is successfully connected
 */
 @Override
 public void onConnected(@Nullable Bundle bundle) {
  //We set a listener to our button only when the ApiClient is connected successfully
  locationButton.setOnClickListener(this);
 }

 //This callback is invoked when the user grants or rejects the location permission
 @Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

  switch (requestCode) {
   case LOCATION_REQUEST:
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
     getCurrentLocation();
    } else
     Toast.makeText(this, "Location permission denied", Toast.LENGTH_SHORT);
    break;

  }
 }

 private void getCurrentLocation() {
  //Checking if the location permission is granted
  if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
   ActivityCompat.requestPermissions(this, new String[] {
    Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION
   }, LOCATION_REQUEST);
   return;
  }

  //Fetching location using FusedLOcationProviderAPI
  FusedLocationProviderApi fusedLocationApi = LocationServices.FusedLocationApi;
  Location location = fusedLocationApi.getLastLocation(googleApiClient);

  //In some rare cases Location obtained can be null
  if (location == null)
   locationText.setText("Not able to fetch location");
  else
   locationText.setText("Location co-ord are " + location.getLatitude() + "," + location.getLongitude());

 }

 //Callback invoked if the GoogleApiClient connection is suspended
 @Override
 public void onConnectionSuspended(int i) {
  Toast.makeText(this, "Connection was suspended", Toast.LENGTH_SHORT);
 }

 //Callback invoked if the GoogleApiClient connection fails
 @Override
 public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
  Toast.makeText(this, "Connection failed", Toast.LENGTH_SHORT);
 }

 @Override
 public void onClick(View view) {
  switch (view.getId()) {
   case R.id.location_btn:
    getCurrentLocation();
    break;

  }
 }
}

 

 

Screenshot_2017-08-24-20-43-14

 

That is how simple it is to fetch location using Google APIs. Apart from the simplicity its found more accurate and easy to work with. If you liked this article please share it with your friends and comment below for any questions /suggestion. If you want to know to integrate Google maps and show the current location inside a Map please read this

 


Spread knowledge

1 Reply to “Android Example : Fetching Current Location with FusedLocationProviderAPI”

Leave a Reply

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