Android Location Fused Provider

Last modified on June 19th, 2017 by Joe.

This Android tutorial is to explain what a fused location provider is and how to use it to get the location using a sample Android application. We need not explicitly choose either GPS or Network location Provider, as the “Fused Location Provider” automatically chooses the underlying technology and gives the best location as per the need.

Location

In this tutorial we will be using the FusedLocationProviderApi which is the latest API and the best among the available possibilities to get location in Android. If for some reason you wish to use the old APIs then refer the earlier written tutorial to get current location in Android.

Fused Location Provider

Three Use Cases for location access

With respect to fused location provider, we can broadly classify the API usage in three use cases.

  1. getLastLocation(GoogleApiClient) this API should be used when there is no need for continuous access to location from an application. Like one shot access or get user location based on some action. This is the simplified way to get the device location and also may not provide high accuracy.
  2. requestLocationUpdates(GoogleApiClient,LocationRequest, LocationListener) this API should be used when there a need for continuous location updates and the location is accessed when the application is active in foreground.
  3. requestLocationUpdates (GoogleApiClient, LocationRequest, PendingIntent) this API is used to receive location updates in the background even when the application is not active. So the difference is PendingIntent.

Android-Fused-Location-Continuous-Access

Example Android Application to Get Location

Download

Following is an example Android application that shows how to get the current user location. This also continuously updates the location on the move.

Prerequisite

Google Play Services is required. If you are using Android Studio and Gradle, you should have the following dependencies added in build.gradle file

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.google.android.gms:play-services:6.5.87'
}

Note: As of now(14 March 2015), Fused location provider API is not working in all the Android Nexus virtual device emulators. Its a widely reported defect. You can use any other AVD to test in the emulator like WVGA AVDs. I used “4 WVGA API 21” virtual device in emulator to test it. It is also working on a real device and I tested it in Panasonic P81.

AndroidManifest.xml

Remember to give access permissions as shown below. You need not give permission for GPS, Network providers. I have seen Android location access tutorial examples giving all the available permission in the world. Just on android.permission.ACCESS_FINE_LOCATION is enough.

ACCESS_COARSE_LOCATION permission is for approximate location access using cell towers and Wi-Fi. ACCESS_FINE_LOCATION is for precise location access using GPS or cell towers and Wi-Fi. Choose the one that is appropriate for you and do not give both. Battery power is used accordingly.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javapapers.android.androidlocation" >
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".LocationActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>

</manifest>

FusedLocationProviderApi Usage

FusedLocationProviderApi

FusedLocationProviderApi can be accessed via LocationServices as below,

    private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;

GoogleApiClient

FusedLocationProviderApi requires the GoogleApiClient instance to get the Location and it can be obtained as below.

	googleApiClient = new GoogleApiClient.Builder(locationActivity)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

Location Interface Implementations for Callbacks

The following interfaces should be implemented to get the location update.

Continuous Location Access Activity

Following is the complete class which accesses the Fused Location Provider to get the location continuously in the Android example application.

package com.javapapers.android.androidlocation;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.text.DateFormat;
import java.util.Date;

public class LocationActivity extends Activity implements
        LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "LocationActivity";
    private static final long INTERVAL = 1000 * 10;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    Button btnFusedLocation;
    TextView tvLocation;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mCurrentLocation;
    String mLastUpdateTime;

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate ...............................");
        //show error dialog if GoolglePlayServices not available
        if (!isGooglePlayServicesAvailable()) {
            finish();
        }
        createLocationRequest();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        setContentView(R.layout.activity_main);
        tvLocation = (TextView) findViewById(R.id.tvLocation);

        btnFusedLocation = (Button) findViewById(R.id.btnShowLocation);
        btnFusedLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                updateUI();
            }
        });

    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart fired ..............");
        mGoogleApiClient.connect();
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop fired ..............");
        mGoogleApiClient.disconnect();
        Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
    }

    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
        startLocationUpdates();
    }

    protected void startLocationUpdates() {
        PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
        Log.d(TAG, "Location update started ..............: ");
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.d(TAG, "Connection failed: " + connectionResult.toString());
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG, "Firing onLocationChanged..............................................");
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        updateUI();
    }

    private void updateUI() {
        Log.d(TAG, "UI update initiated .............");
        if (null != mCurrentLocation) {
            String lat = String.valueOf(mCurrentLocation.getLatitude());
            String lng = String.valueOf(mCurrentLocation.getLongitude());
            tvLocation.setText("At Time: " + mLastUpdateTime + "\n" +
                    "Latitude: " + lat + "\n" +
                    "Longitude: " + lng + "\n" +
                    "Accuracy: " + mCurrentLocation.getAccuracy() + "\n" +
                    "Provider: " + mCurrentLocation.getProvider());
        } else {
            Log.d(TAG, "location is null ...............");
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopLocationUpdates();
    }

    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
        Log.d(TAG, "Location update stopped .......................");
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mGoogleApiClient.isConnected()) {
            startLocationUpdates();
            Log.d(TAG, "Location update resumed .....................");
        }
    }
}

Android Layout File

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".LocationActivity"
    android:background="#ffffa6c7">

    <TextView
        android:text="@string/locationTxt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:layout_centerHorizontal="true" />

    <Button
        style="?android:attr/buttonStyleSmall"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Show Location"
        android:id="@+id/btnShowLocation"
        android:layout_toEndOf="@+id/textView"
        android:layout_marginTop="53dp"
        android:layout_below="@+id/textView"
        android:layout_alignParentStart="true"
        android:layout_centerHorizontal="true"
        android:background="#ffff1a7c"
        android:textColor="#ffffffff" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tvLocation"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="134dp"
        android:layout_alignParentEnd="true" />

</RelativeLayout>

Test Run the Location Application via Android Emulator

In Eclipse, Open DDMS perspective (Window -> Open Perspective)

In Android Studio, open Android Device Monitor

  • The below screen shot will help,
    Location-Latitude-Longitude-Via-Emulator
  • Download

    Comments on "Android Location Fused Provider"

    1. […] This tutorial is to learn how to show the current location on map in an Android application using Google Maps API. Previously we have seen tutorials to get the current location using the different location providers. If you are looking to just get the latitude and longitude of a location, the refer get current location using Android Fused location provider tutorial. […]

    2. N says:

      Thank you! I couldn’t find a specific example of grabbing the fused provider anywhere until getting here.

    3. Naphtali Gilead says:

      This tutorial is great!
      Is there another way to get the location as soon as see the activity on my screen in oppose to clicking a button?
      I’ve tried placing the request for location in onCreate, onStart and onResume, but that only works in onResume after I really resume from standby.

    4. HieuND says:

      Thanks you, this tutorial is so great. Have a nice day!

    5. Sapersky says:

      Hi

      After implementing it I’m getting no Location at all. I’m not even getting default status icon when some app is trying to get the current location. With previous examples it worked fine.

      I have

      in build.gradle:

      dependencies {
      compile fileTree(dir: ‘libs’, include: [‘*.jar’])
      compile ‘com.android.support:appcompat-v7:21.0.3’
      compile ‘com.google.android.gms:play-services:6.5.87’
      }
      And in activity:
      if (!isGooglePlayServicesAvailable()) {
      finish();
      }
      setContentView(R.layout.map_layout);

      fusedLocationService = new FusedLocationService(this);
      tvLocation = (TextView) findViewById(R.id.curPositionText);

      Location location = fusedLocationService.getLocation();
      String locationResult;
      if (null != location) {
      Log.i(TAG, location.toString());
      double latitude = location.getLatitude();
      double longitude = location.getLongitude();
      // float accuracy = location.getAccuracy();
      // double elapsedTimeSecs = (double) location.getElapsedRealtimeNanos()
      // / 1000000000.0;
      // String provider = location.getProvider();
      // double altitude = location.getAltitude();
      locationResult = “Latitude: ” + latitude +
      ” Longitude: ” + longitude;
      } else {
      locationResult = “Location Not Available!”;
      }
      tvLocation.setText(locationResult);

      Any idea?

    6. Paul says:

      Joe,

      Excellent tutorial!

      How would I setup pooling so that I can send the onChanged() location from the FusedLocationService back to the View without having to click on the button?

      Thanks,
      Paul

    7. Paul says:

      Pardon the misspelling, I meant polling.

    8. William Rondon says:

      Excellent work as well. Thank You.

    9. Daniel says:

      Hello!

      Great tutorial, but I have a problem. I tried it and it works on emulator (Nexus 4), but on my real device Samsung Galaxy mini (2.3.6) it starts, but when I click the button (“Show Location”) an error message pop up and the program is closing automatically. Can you help me? What can be the problem? I do have google service, I was connecting to Wifi, I have mobile net, but my GPS location probably wasn’t found, because I was indoor (but this is why I need fuse location, so I guess it can’t be a problem).

      Thanks,
      Daniel

    10. Joe says:

      @Naphtali, @Paul and @Daniel,

      I have updated the tutorial and fixed some defects in it. Added feature to get location onChange. Now dynamically the location will be updated when the device gets a new location. Need not click the button to get the location. Now it is tested in both Emulator and real device.

      Let me know if you guys need anything more in this tutorial.

    11. […] the Android location using fused provider tutorial to understand better about the Android fused location provider API and how it can be used […]

    12. Ramulu P says:

      Hi Joe,

      I implemented your code in my eclipse and tried to run in emulator.But on clicking show location i am not getting anything displayed in emulator and location “null” showing in log.

      Would you please help anything i am missing.

    13. Bert says:

      How do we know if getLastLocation is not an obsolete location? Google documentation mentions that it may be null however it does not say how old it may be?

    14. amit says:

      Is fused API will give me exact result or exact location because some time GPS is switching the location ?

    15. Paritosh Sumrao says:

      Best Android tutorials I found so far. I wanst getting how to go about fusedLocationApi. But this made my life a lot easier. Thanks a lot..

    16. Khem Singh says:

      Hi,
      its Very Nice Tutorial. I have a Question can we on the gps or location service automatically without user manually in android if yes then please share the flow.

      thanks

    17. Kishan Gandhi says:

      Hi,
      Thank you Sir for this great tutorial. Worked perfectly. I have a couple of queries.
      1. How can i use PendingIntenet for getting location updates when app is running in background (A short snippet will be gr8).
      2. What if the WiFi is OFF? From where are the location coordinated are retrieved?

      Thanks.

    18. Ravi Gehlot says:

      Thank You Very Much!!
      This helped me alot for my application.
      and its really simple also if you follow this completely.

    19. Magaly Gutierrez says:

      This tutorial is great except I have one question. I am trying to implement the request in a class and upload the results in a separate class which happens to be a fragment. What should I use in place of “this” when building the GoogleApiClient and where should I call connect from? From the OnCreateView method? Thank you

    20. eben says:

      hi, thanks for this great tutorials. i have followed it but i am not receiving any location. it is always null. please help me

    21. Juanma says:

      I’m developing an app using this fused location provider and all seems to work good. But the problems I have is that the locations I get dont have any information about altitude.

    22. Vinayak says:

      Can it works when i am in offline?Plz reply any one

    23. Nithien Badal says:

      Thank you. May you have peace knowing that your social role and function is well and effective.

    Comments are closed for "Android Location Fused Provider".