One of the major features of android framework is location API. You can see, the location module widely used in lot of apps those provides services like food ordering, transportation, health tracking, social networking and lot more. The location module is part of Google Play Services and in the same module geofencing and activity recognition are included.

In this article we are going to cover the basics of location API with an example app.


1. Introduction

Earlier, getting location is very easy with couple of API calls. But to provide more accurate locations and optimizing the battery usage, Android introduced set APIs that should be combined to get the best results from the location API. We will be using Fused Location API that combines signals from GPS, Wi-Fi, and cell networks, as well as accelerometer, gyroscope, magnetometer and other sensors to provide more accurate results.

1.1 Location Permissions

There are two permissions available to request location. The accuracy of the location is determined by the kind of permission requested and priority level.

  • ACCESS_COARSE_LOCATION: Gives location approximately equivalent to a city block.
  • ACCESS_FINE_LOCATION: Gives precise location, sometimes in few meters or feet when combined with High Priority accuracy.

1.2 Receiving Location Updates

  • getLastLocation(): Returns the recent available location. When location is not available, it returns null.
  • Location Settings: In order to get the location, proper settings has to enabled in the device such as GPS or Wifi. Instead of requesting the user to enable them separately, you can use Settings Client to check whether proper settings are enabled or not. If enabled, you can proceed with location updates or user will be shown a dialog to turn on the required hardware as shown below.
  • Update Interval: This interval defines the rate in milliseconds at which your app prefers the location updates. Your app can receive updates lesser or higher than this rate if other apps requested location updates higher than your value. Let’s say your app requests updates every 10secs, if other app is requesting updates at 5secs, your app might receives the same updates ignoring the 10sec value.
  • Fastest Update Interval: This is the rate at which your app can handle the location updates. Without this value, you can see inconsistent user experience if your app can’t handle frequent location updates.
  • Priority: The accuracy of the location depends on the source of the hardware used. To define this, Priority has to be mentioned while requesting the location. The priority can be BALANCED, HIGH, LOW OR NO_POWER.

1.3 Example App

Here is the demo app we are going to implement in this article. The app receives the location updates when it is opened and updates will be stopped when app goes to background.


Let’s jump to coding part by creating a new project in Android Studio.

2. Creating New Project

1. Create a new project in Android Studio from File ⇒ New Project and select Basic Activity from templates.

2. Open res/strings.xml and add the below string resources.

    <string name="app_name">Android Location</string>
    <string name="start_updates">START LOCATION UPDATES</string>
    <string name="stop_updates">STOP LOCATION UPDATES</string>
    <string name="get_last_location">GET LAST LOCATION</string>

3. Add ACCESS_FINE_LOCATION permission to your AndroidManifest.xml.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""

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



4. Open app/build.gradle and add location play service dependency. We also need Dexter (Runtime Permissions) and ButterKnife (View Binding) libraries.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // location play services
    implementation ''

    // dexter runtime permissions
    implementation 'com.karumi:dexter:4.2.0'

    // ButterKnife view binding
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

5. Open the layout file of main activity activity_main.xml and add the below code. In this layout, few Buttons and TextViews are defined to toggle the location updates and display location information.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""

        android:text="@string/start_updates" />

        android:text="@string/stop_updates" />

        android:text="@string/get_last_location" />

        android:text="Location updates will be received only when app is foreground" />

        android:textSize="18dp" />

        android:textSize="11dp" />

6. Open and add the below code. Initially the code might look heavy but with couple of observations you can understand it easily.

  • First we initialize all the location related clients such as FusedLocationProviderClient, LocationRequest, LocationSettingsRequest, LocationCallback and SettingsClient in onCreate() method.
  • While initializing, we define the interval setInterval(), fastest interval setFastestInterval() and priority setPriority() on location request.
  • Dexter is used to request the location permission before performing any location related operations.
  • startLocationUpdates() requests for location updates. First, it checks whether the location settings are eanbled and once satisfied, the updates will be requested. Here SettingsClient is used to check for settings configuration.
  • The location updates will be received in LocationCallback and proper UI action is taken place. If you really want to the location only once, you can call stopLocationUpdates() method immediately after receiving the first location update.
  • The location updates are paused and resume in onPause() and onResume() method to save the batter power.
package info.androidhive.androidlocation;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;

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

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

 * Reference:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    TextView txtLocationResult;

    TextView txtUpdatedOn;

    Button btnStartUpdates;

    Button btnStopUpdates;

    // location last updated time
    private String mLastUpdateTime;

    // location updates interval - 10sec
    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;

    // fastest updates interval - 5 sec
    // location updates will be received if another app is requesting the locations
    // than your app can handle
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 5000;

    private static final int REQUEST_CHECK_SETTINGS = 100;

    // bunch of location related apis
    private FusedLocationProviderClient mFusedLocationClient;
    private SettingsClient mSettingsClient;
    private LocationRequest mLocationRequest;
    private LocationSettingsRequest mLocationSettingsRequest;
    private LocationCallback mLocationCallback;
    private Location mCurrentLocation;

    // boolean flag to toggle the ui
    private Boolean mRequestingLocationUpdates;

    protected void onCreate(Bundle savedInstanceState) {

        // initialize the necessary libraries

        // restore the values from saved instance state

    private void init() {
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        mSettingsClient = LocationServices.getSettingsClient(this);

        mLocationCallback = new LocationCallback() {
            public void onLocationResult(LocationResult locationResult) {
                // location is received
                mCurrentLocation = locationResult.getLastLocation();
                mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());


        mRequestingLocationUpdates = false;

        mLocationRequest = new LocationRequest();

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        mLocationSettingsRequest =;

     * Restoring values from saved instance state
    private void restoreValuesFromBundle(Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            if (savedInstanceState.containsKey("is_requesting_updates")) {
                mRequestingLocationUpdates = savedInstanceState.getBoolean("is_requesting_updates");

            if (savedInstanceState.containsKey("last_known_location")) {
                mCurrentLocation = savedInstanceState.getParcelable("last_known_location");

            if (savedInstanceState.containsKey("last_updated_on")) {
                mLastUpdateTime = savedInstanceState.getString("last_updated_on");


     * Update the UI displaying the location data
     * and toggling the buttons
    private void updateLocationUI() {
        if (mCurrentLocation != null) {
                    "Lat: " + mCurrentLocation.getLatitude() + ", " +
                            "Lng: " + mCurrentLocation.getLongitude()

            // giving a blink animation on TextView

            // location last updated time
            txtUpdatedOn.setText("Last updated on: " + mLastUpdateTime);


    public void onSaveInstanceState(Bundle outState) {
        outState.putBoolean("is_requesting_updates", mRequestingLocationUpdates);
        outState.putParcelable("last_known_location", mCurrentLocation);
        outState.putString("last_updated_on", mLastUpdateTime);


    private void toggleButtons() {
        if (mRequestingLocationUpdates) {
        } else {

     * Starting location updates
     * Check whether location settings are satisfied and then
     * location updates will be requested
    private void startLocationUpdates() {
                .addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                        Log.i(TAG, "All location settings are satisfied.");

                        Toast.makeText(getApplicationContext(), "Started location updates!", Toast.LENGTH_SHORT).show();

                        //noinspection MissingPermission
                                mLocationCallback, Looper.myLooper());

                .addOnFailureListener(this, new OnFailureListener() {
                    public void onFailure(@NonNull Exception e) {
                        int statusCode = ((ApiException) e).getStatusCode();
                        switch (statusCode) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                Log.i(TAG, "Location settings are not satisfied. Attempting to upgrade " +
                                        "location settings ");
                                try {
                                    // Show the dialog by calling startResolutionForResult(), and check the
                                    // result in onActivityResult().
                                    ResolvableApiException rae = (ResolvableApiException) e;
                                    rae.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                                } catch (IntentSender.SendIntentException sie) {
                                    Log.i(TAG, "PendingIntent unable to execute request.");
                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                String errorMessage = "Location settings are inadequate, and cannot be " +
                                        "fixed here. Fix in Settings.";
                                Log.e(TAG, errorMessage);

                                Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();


    public void startLocationButtonClick() {
        // Requesting ACCESS_FINE_LOCATION using Dexter library
                .withListener(new PermissionListener() {
                    public void onPermissionGranted(PermissionGrantedResponse response) {
                        mRequestingLocationUpdates = true;

                    public void onPermissionDenied(PermissionDeniedResponse response) {
                        if (response.isPermanentlyDenied()) {
                            // open device settings when the permission is
                            // denied permanently

                    public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {

    public void stopLocationButtonClick() {
        mRequestingLocationUpdates = false;

    public void stopLocationUpdates() {
        // Removing location updates
                .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                    public void onComplete(@NonNull Task<Void> task) {
                        Toast.makeText(getApplicationContext(), "Location updates stopped!", Toast.LENGTH_SHORT).show();

    public void showLastKnownLocation() {
        if (mCurrentLocation != null) {
            Toast.makeText(getApplicationContext(), "Lat: " + mCurrentLocation.getLatitude()
                    + ", Lng: " + mCurrentLocation.getLongitude(), Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(), "Last known location is not available!", Toast.LENGTH_SHORT).show();

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            // Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        Log.e(TAG, "User agreed to make required location settings changes.");
                        // Nothing to do. startLocationupdates() gets called in onResume again.
                    case Activity.RESULT_CANCELED:
                        Log.e(TAG, "User chose not to make required location settings changes.");
                        mRequestingLocationUpdates = false;

    private void openSettings() {
        Intent intent = new Intent();
        Uri uri = Uri.fromParts("package",
                BuildConfig.APPLICATION_ID, null);

    public void onResume() {

        // Resuming location updates depending on button state and
        // allowed permissions
        if (mRequestingLocationUpdates && checkPermissions()) {


    private boolean checkPermissions() {
        int permissionState = ActivityCompat.checkSelfPermission(this,
        return permissionState == PackageManager.PERMISSION_GRANTED;

    protected void onPause() {

        if (mRequestingLocationUpdates) {
            // pausing location updates

Run the app in emulator or on a real device to see it working.



> The code samples used in this article are highly forked from the Github Location Sample with few modifications and bug fixes.

> I strongly suggest you to go through Location Docs for detailed explanation of location API.

> Here are some best practises to optimize the battery usage.

Hi there! I am Founder at androidhive and programming enthusiast. My skills includes Android, iOS, PHP, Ruby on Rails and lot more. If you have any idea that you would want me to develop? Let’s talk:
  • Tiara Gizka Septi

    thansk for your tutorial, but Is it possible to get a location without internet?


    • preeti agarwal

      I need algorithm with accuracy without internet

  • Rohit Bansal

    lat long is showing 0,0

    • Shehzad Android Developer

      lat long is showing 0,0

      • В’ячеслав Лук’янов

        Try using
        in manifest or turn on geolocation in google map on your device

  • chandrahas

    i want this example in android studio

  • chandrahas

    i want this code for android studio

  • anamika

    hi … can any one tell how to use heading and coarse in android to get the direction of moving device.

  • Thanks for the tutorial but it’s outdated.
    I’ve tried several methods but none of them works, including this one.
    As far as I know, the problem is that the methods of getting location has changed a lot.
    Can you post the updated method please?

    • Yes, I have to update this article. Meanwhile try learning about Google Fused Location API.

      • Thanks for the reply Ravi 🙂

      • Dohab M

        They claimed that Fused Location is faster, well, thats not right. I tried both, and found that LocationManager is way faster, better, and easier.
        Thanks for coding.

      • Farrukh Saleem

        Hi Sir Ravi.
        i want to open this project in android studio i am fail. it can not show gradle file in android.
        please guide me

  • yus ala

    hi Ravi thanks for the tutorial,one question if I want to store the location to database, can you show me how to do that?

    • Nurdaulet Yeltayev

      To store location you can use SQL Database

  • David Pagliotto

    Great help!
    Tnks to share this…

    It’s works.

  • umesh

    hello sir,every time i am using gps its gives me 0.0 lat long ….any specific reason for this.

    • I am sorry the article is very old. Please read the docs from android about fused location api. I’ll update this article.

    • Make sure have write the following permission in your manifest () :


      In my case i forget to write the second permission

  • Ali Gassan

    the problem for get a value of 0.0 lat long , the permission is not allowed for gps , you can check that from setting phone, you will see ” no permissions allowed “


      give ur app permission for location manually in setting

  • Karthikeyan

    I am using your above code to get location. my problem is, prompts the user to enable GPS if it’s not on and I have used AlertDialog for this purpose. After I enable the GPS from settings and come back to my app by pressing back button, the toast message display 0.00,0.00. Although If I have my GPS on before running the app, the app properly displays my location. I want to know to which method to use for this refresh user location after enabling GPS purpose. Any relevant article would really help.

    • Karthikeyan

      i need a reply @ravi8x:disqus

    • Once you got this article. Try integrating Fusion location api.

  • Md. Azizul Alam (Toton)

    Hi Ravi, Can you little bit explain how can I send this periodic data to server through Volley with this interval or location change?

  • Satnam Singh

    Hi i am using your tutorial it is working in MI phones but surprisingly it does not work in Samsung On8 ..
    it getting null
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    mLastLocation ==null

    could you please help me here.

  • Im Ug

    I have a question. I have many GPS modules that I can connect to my PC via FT232 or CP2102. Can I use them with an Android emulator together with this GPS API? If yes, how?

  • 신종호 (ABCDEFG)

    I created the app as above code. However, the current coordinates are received as latitude: 0.0 longitude: 0.0.
    What is the problem?

  • Imtiyaz Khalani
  • Prabhu Yuvaa

    I Need to send latitude and longitude to mysql database from android app using php api.. can you help me please


    after generating apk the app keeps stopping

  • Gunjan Sharma

    When i run the application it is showing lat and long both are 0 ….
    please help me to solve this issue

    • hala

      Please, I have the same problem
      How could you solve it??

  • DirectionalAudio DirectionalAu

    I have to implement onRequestPermissionsResult() for this GPSTRACKER SERVICE how to do that?

  • inderjit singh

    i need current location of user with the help of GPS provider.

    Currently i’m getting GPS location, but in some devices i’m not getting location.

    I also tried last known location and network location, but they are not accurate.

    So please help by providing better solution.

  • Ashok Sennan

    i want to get the exact latitude and longitude of it posible in gpstracking??

    • Michael Lukin

      Yes, there is a section “Getting Latitude and Longitude” in this article

  • shivani

    hey hi can you help me out with google map v2 error ??
    Well my issue is : I can see the route with markers when i debug the code on my device but can see blank map when i run the same code on the same device

  • Smita Sonavane

    Even though location mode is with high accuracy, sometimes code returns null location value continuously what should I do at that time?

    • Hi Smita

      I suggest you go through google docs while I update this article with latest apis.

      • Naeem Iqab

        For android versions above 6.0, It should ask for location permission

  • suraj bhuturle

    How to restrict mock location in this code and get accurate location.

  • nikil

    hi sir , i have a toggle button in my app and when click on in toggle button the page will redirect to another page

  • shiva yadav

    Hi Sir,

  • Tuan Tran

    Hi sir i just done making this, but i’m getting latiture and longtiture has values is 0.0. i’m running on device not emulator. Can you help me

    • hala

      a few seconds ago
      Please, I have the same problem
      How could you solve it??

  • fadhol

    in new apis value of lat and lng is 0.0, please help sir

    • hala

      Please, I have the same problem
      How could you solve it??

  • hala

    Location is set on 0، 0
    It is not moving to my current location
    Please help me
    I have been trying to fix it for many days but it doesnt change
    Please help

  • Pankaj Choudhary

    sir…can you provide me source code to generate real time location sharing …..its urgent sir…

  • kainat

    hi your tutorial is very helpful
    i want to ask that i want to save my current latitude and longitude in database automatically that is when someone login to my application his/her current latitude and longitude should be save automatically in database and then i want it to be show on google map can u plz help me
    Thanks in advance

  • Manuel

    Hey, thank you for the helpful tutorial. While implementing a similar location management I got to the question, if there is a special reason, that you decided to use the network provider first, and only if no location is found by that, the location is determined by gps?

  • Nitul Barman

    thank you for the tutorial.. but it only shows latitude and longitude with wifi connection . please help

  • TAGNE TOKAM Cedrick Gaetan


  • TAGNE TOKAM Cedrick Gaetan

    Please I always have 0.0 as longitude and as latitude can you please help me?

    • alex

      check your permissions

  • jayesh

    Hello sir,
    this demo completely work in other mobile but in moto and Samsung i always get 0 value.
    i have already code to run time permission and also check permission in setting all is done but i get o lat long
    please give me reply what can i do??

    • Have you integrated the run time permissions? Also consider using FusedLocationApi.

    • Hi

      The article is just updated with the latest APIs. Please check now.

  • Instead of plotting them on map, print them to log and compare values.

  • Muthu S

    Hi Ravi,

    I am fan of your tutorials.. I want background service to get location with or without internet. Is it possible.. if so any help or tutorial please..

  • How to get location when app is background?

    • Try the other samples provided in the google sample. The link is provided at the bottom.

  • keighb
  • Ameet Pawar

    thanku very much sir saved my day

  • Adnan khan

    in my app i call this startLocationButtonClick() function direction means without clicklistener .After that dialogue box can not cancel and show again until i click on ok button

  • Kumararaja

    i need to calculate distance from new lat & lang position, help me

  • Cuk Duarte

    hi ravi i want to calculate the root from where am i now to the place i want to go

  • Samy Lengue

    Your code is super Ravi. Thanks a lot.

  • Ogi Doank

    Hello ravi i have a question, how to convert lang and long to real addresses i got null when i toke the data TextView full_address;
    Geocoder geocoder;
    List addresses;
    full_address = (TextView) findViewById(;
    geocoder = new Geocoder(this, Locale.getDefault());

    try {
    if(mCurrentLocation != null){
    addresses = geocoder.getFromLocation(

    String address = addresses.get(0).getAddressLine(0);
    String area = addresses.get(0).getLocality();
    String city = addresses.get(0).getAdminArea();
    String country = addresses.get(0).getCountryName();
    String postalcode = addresses.get(0).getPostalCode();

    String fulladdress = address+”, “+area+”, “+city+”, “+country+”, “+postalcode;


    // giving a blink animation on TextView

    } catch (IOException e){

    I got null can you please help me out?

  • Ogi Doank
  • aravind meshram

    above this code is successfully but i have one question how to get background location even app is closed…please reply me

  • Riky Setiawan

    i can give you donate?

  • Pradeep Doraiswamy

    @ravi8x:disqus I need to send location details to server for every 5 sec . can you give some kind tips n correct way to implement it .

  • josileudo rodrigues de freitas

    how would I do to store these coordinates in a database or in a txt file?

  • Bhupinder Tandon

    Execution failed for task ‘:app:mergeExtDexDebug’.
    > Could not resolve all files for configuration ‘:app:debugRuntimeClasspath’.
    > Failed to transform artifact ‘butterknife-runtime.aar (com.jakewharton:butterknife-runtime:10.1.0)’ to match attributes {artifactType=android-dex, dexing-is-debuggable=true, dexing-min-sdk=15}
    > Execution failed for DexingTransform: C:Userssekho.gradlecachestransforms-2files-2.15f5876ab8d9a6306a6feca8b1586fa7ajarsclasses.jar.
    > Error while dexing.
    could you plz help to resolve this error

  • pradeepkumar reddy

    How to get location updates even after the app is killed ??

  • pradeepkumar reddy

    Here why are you using Looper.myLooper(), instead of Looper.getMainLooper() ??

  • pradeepkumar reddy

    In a foreground service, i’m using FusedLocationProviderClient to request for location updates. I’m using foreground service because, i want location updates even when the app is closed. so far so good. it is working. But the problem is, if the gps is turned off then i’m not getting the onLocationResult() call back. How to handle this problem ?? Before starting the service, location was on and i got a couple of callbacks in onLocationResult() method. After sometime, user turned off the gps, after that i’m not getting the onLocationResult() call back. Any idea how to deal with this problem ??