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.

android-recyclerview-databinding-example

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.
    android-location-settings-dialog
  • 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.

android-location-tutorial

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.

<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>
</resources>

3. Add ACCESS_FINE_LOCATION permission to your AndroidManifest.xml.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.androidlocation">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        ...>
    </application>

</manifest>

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 'com.google.android.gms:play-services-location:15.0.1'

    // 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="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"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    tools:context=".MainActivityOld">

    <Button
        android:id="@+id/btn_start_location_updates"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dp"
        android:text="@string/start_updates" />

    <Button
        android:id="@+id/btn_stop_location_updates"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:enabled="false"
        android:text="@string/stop_updates" />

    <Button
        android:id="@+id/btn_get_last_location"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="@string/get_last_location" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:gravity="center_horizontal"
        android:text="Location updates will be received only when app is foreground" />

    <TextView
        android:id="@+id/location_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textColor="#333"
        android:textSize="18dp" />

    <TextView
        android:id="@+id/updated_on"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:textSize="11dp" />
</LinearLayout>

6. Open MainActivity.java 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.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
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: https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates
 */

public class MainActivity extends AppCompatActivity {

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

    @BindView(R.id.location_result)
    TextView txtLocationResult;

    @BindView(R.id.updated_on)
    TextView txtUpdatedOn;

    @BindView(R.id.btn_start_location_updates)
    Button btnStartUpdates;

    @BindView(R.id.btn_stop_location_updates)
    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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        // initialize the necessary libraries
        init();

        // restore the values from saved instance state
        restoreValuesFromBundle(savedInstanceState);
    }

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

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

                updateLocationUI();
            }
        };

        mRequestingLocationUpdates = false;

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        mLocationSettingsRequest = builder.build();
    }

    /**
     * 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");
            }
        }

        updateLocationUI();
    }


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

            // giving a blink animation on TextView
            txtLocationResult.setAlpha(0);
            txtLocationResult.animate().alpha(1).setDuration(300);

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

        toggleButtons();
    }

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

    }

    private void toggleButtons() {
        if (mRequestingLocationUpdates) {
            btnStartUpdates.setEnabled(false);
            btnStopUpdates.setEnabled(true);
        } else {
            btnStartUpdates.setEnabled(true);
            btnStopUpdates.setEnabled(false);
        }
    }

    /**
     * Starting location updates
     * Check whether location settings are satisfied and then
     * location updates will be requested
     */
    private void startLocationUpdates() {
        mSettingsClient
                .checkLocationSettings(mLocationSettingsRequest)
                .addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
                    @SuppressLint("MissingPermission")
                    @Override
                    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
                        mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                                mLocationCallback, Looper.myLooper());

                        updateLocationUI();
                    }
                })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    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.");
                                }
                                break;
                            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();
                        }

                        updateLocationUI();
                    }
                });
    }

    @OnClick(R.id.btn_start_location_updates)
    public void startLocationButtonClick() {
        // Requesting ACCESS_FINE_LOCATION using Dexter library
        Dexter.withActivity(this)
                .withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
                .withListener(new PermissionListener() {
                    @Override
                    public void onPermissionGranted(PermissionGrantedResponse response) {
                        mRequestingLocationUpdates = true;
                        startLocationUpdates();
                    }

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

                    @Override
                    public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
                        token.continuePermissionRequest();
                    }
                }).check();
    }

    @OnClick(R.id.btn_stop_location_updates)
    public void stopLocationButtonClick() {
        mRequestingLocationUpdates = false;
        stopLocationUpdates();
    }

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

    @OnClick(R.id.btn_get_last_location)
    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();
        }
    }

    @Override
    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.
                        break;
                    case Activity.RESULT_CANCELED:
                        Log.e(TAG, "User chose not to make required location settings changes.");
                        mRequestingLocationUpdates = false;
                        break;
                }
                break;
        }
    }

    private void openSettings() {
        Intent intent = new Intent();
        intent.setAction(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package",
                BuildConfig.APPLICATION_ID, null);
        intent.setData(uri);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

    @Override
    public void onResume() {
        super.onResume();

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

        updateLocationUI();
    }

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


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

        if (mRequestingLocationUpdates) {
            // pausing location updates
            stopLocationUpdates();
        }
    }
}

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

android-location-update-using-google-fused-api

References

> 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.

Subscribe
Notify of
guest
223 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Julio Vergara
Julio Vergara
5 years ago

Excellent Ravi, usefull tutorial

chantanz
chantanz
5 years ago

thanks Ravi for this nice tutorial

Sult'one
Sult'one
5 years ago

Works perfectly, thank you Ravi 🙂

Paresh Mayani
5 years ago

I am wondering you are still demoing using Eclipse! Setting dependencies and using them is damm easy in Android studio.

Another thing is you have used LocationClient class, which is deprecated!

Alok Nair
Alok Nair
5 years ago
Reply to  Paresh Mayani

Hi Paresh,

LocationClient is deprecated, but not LocationRequest. When did LocationRequest class become deprecated. 😛

Paresh Mayani
5 years ago
Reply to  Alok Nair

Ohh yeah….that’s my mistake! I was talking about LocationClient only.

Ravi Tamada
5 years ago
Reply to  Paresh Mayani

Got it. Let me check that … thanx 🙂

Alok Nair
Alok Nair
5 years ago
Reply to  Paresh Mayani

🙂

Adam
Adam
5 years ago

Any chance of future tutorial using Android Studio as the IDE?

Raihan Rian
Raihan Rian
5 years ago

Great tutorial …..brother …please make a weather app tutorial brother

Aguirre
Aguirre
5 years ago

Why not Android Studio? Anyway! Still a great tutorial. Cheers!

Ravi Tamada
5 years ago
Reply to  Aguirre

I do use Android Studio. But I have to write a tutorial about AS first before publishing my articles using AS.

Aguirre
Aguirre
5 years ago
Reply to  Ravi Tamada

I see. That’s pretty good. Start on basic to avoid confusion using the new IDE. Cheers!

Ravi Tamada
5 years ago
Reply to  Aguirre

Well said 🙂

Sumit
Sumit
5 years ago
Reply to  Ravi Tamada

Yes , waiting for Android Studio tutorial.

daniel dizzy
daniel dizzy
5 years ago
Reply to  Ravi Tamada

Same here waiting for Android Studio Tutorials. Thanks Loads Ravi.

s.shivasurya
5 years ago
Reply to  Ravi Tamada

yes! please start creating tag for android studio and it has come to beta version ! i hope! :disqus

Arjun
Arjun
5 years ago

Hello Ravi, ” http://www.androidhive.info/2012/01/android-json-parsing-tutorial/ ” .

I am facing an error in the above Json parsing tutorial link of yours . I just imported the same code in android studio and facing some problems.
Could u guys please help me ? I’m facing this error “24576-24715/info.androidhive.jsonparsing
E/ServiceHandler﹕ Couldn’t get any data from the url”. How to overcome
this ? Please help . Thanks in advance

Rahul Arora
Rahul Arora
5 years ago
Reply to  Arjun

Check your internet connection.

Arjun
Arjun
5 years ago
Reply to  Rahul Arora

It is connnected

Rahul Arora
Rahul Arora
5 years ago
Reply to  Arjun

Actually i use same tutorial for ADT and it’s working fine

Arjun
Arjun
5 years ago
Reply to  Rahul Arora

Got it man. Thanks a ton

Arjun
Arjun
5 years ago
Reply to  Rahul Arora

Hello Rahul, could you help me out to get the image from the json at the right corner of each and every list row for the same tutorial or atleast suggest me a tutorial . Thank you

Rakhi Dhavale
5 years ago

Your tutorials are always great to learn from, so as a Subscriber to your beautiful blog, I request you to please make tutorials on Sync Adapter Framework in Android, where the sync adapter component in the app encapsulates the code for the tasks that transfer data between the device and a server. Thanks 😀 !!

Muhamed
Muhamed
5 years ago

which devices and APIs that works on ?

Francois Lebon-Schneider
Francois Lebon-Schneider
5 years ago

Ravi. I’ve been trying to find your email to contact you. We wanted to forward you a press kit for you to see some things http://disa.im is about to release. It’s seriously groundbreaking technology for mobile device power management and message unification.

We’re releasing very soon, but wanted to give the press and some bloggers a sneak peek as well as a secret press webpage web-link which will give you a preview of the new beta version of the app and the new website.

Contact us back by email when you can or personally message me on hangouts.

karathb
karathb
5 years ago

Gr8! Thx for it! Could you recommend a good geofencing tutorial?

Ravi Tamada
5 years ago
Reply to  karathb
Sai Nalla
Sai Nalla
5 years ago

i am facing error in this tutorial
it shows jar mismatch fix project dependencies how can i solve this
my problem???

Ravi Tamada
5 years ago
Reply to  Sai Nalla

Try to replace the android-support-v4.jar with the jar that found in appcompat_v7 libs folder.

Sai Nalla
Sai Nalla
5 years ago
Reply to  Ravi Tamada

hi

Thats ok!!

i have a small doubt how can i read a pdf file and highlighting the content in pdf in android mobile

is there any app from u?

Vinay Maneti
Vinay Maneti
5 years ago

startLocationUpdates() and startLocationUpdates() methods are used to start/stop the location updates.

In the above sentence the second method is stopLocationUpdates() but in the doc. is mentioned as startLocationUpdates().

Ravi Tamada
5 years ago
Reply to  Vinay Maneti

Thank you vinay. Corrected now.

Guest
Guest
5 years ago
Reply to  Ravi Tamada

(Y)

Allay Khalil
Allay Khalil
5 years ago

I am trying to get sim serial number for both the sim card in a dual sim
android mobile but every time I able to get sim serial number for sim
one but for second sim I am getting null value. any suggestion is
appreciated

SK
SK
5 years ago

Excellent Ravi, usefull tutorial, but i face problems to import import com.google.android.gms.location.LocationServices;.

please help me…..:)

Ravi Tamada
5 years ago
Reply to  SK

Did you added Google Play Services as library project?

Tono
Tono
5 years ago

Hi Ravi, thanks for the code, i have an issue when in “LocationServices.FusedLocationApi.requestLocationUpdates” AS tries to cast third parameter “(com.google.android.gms.location.LocationListener)” anyway it doesn`t work, can you please help me?

tonov
tonov
5 years ago

Hi Ravi, thanks for the code, it works fine except when i try to use startLocationUpdates() in “LocationServices.FusedLocationApi.requestLocationUpdates” AS tries to cast third parameter “(com.google.android.gms.location.LocationListener)” anyway when casting it doesn`t work, can you please help me?

Ravi Tamada
5 years ago
Reply to  tonov

Remove the casting, verify the import statements at the top.

John Antony
John Antony
5 years ago

Nice tutorial …. Which emulator you used in this tutorial bro?

Ravi Tamada
5 years ago
Reply to  John Antony

Its a device bro. I used nexus5 to record the screen and then edited the video placing it on a mobile png image.

Dung
Dung
5 years ago

Thanks tutorial.
I have 20 location (have longitude, latitude) and save it in my database
help me, how to get location near my location (have longitude, latitude)
Ex: 10 meter
😀

Amat Aj
Amat Aj
5 years ago

hi Ravi, I got this problem on

import com.google.android.gms.location.LocationServices;

it seems can’t be fix using Fix Project Setup..

sajid
sajid
5 years ago

i have tested this app but when i click on location updates this message is being shown on the label of get location updates button i have google play services enabled on my device running adnroid 4.2.2 stuck please help me out->: a data connection is required to connect to google playservices,enable google play services

Ravi Tamada
5 years ago
Reply to  sajid

Is your device connected to internet?

sajid
sajid
5 years ago
Reply to  Ravi Tamada

yes everythings is working fine instead of that! my device is also connected to internet actually i am embedding your app to show location on map when , when i click on start location updates that it is giving lat, long values but i have stuck on that ! i m pasting code have a look.
// map_layout.java
package com.example.admin.maps;

import android.app.Activity;

import android.location.Location;

import android.os.Bundle;

import android.support.v4.app.FragmentActivity;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

import android.support.v4.app.FragmentActivity;

import android.support.v7.app.ActionBarActivity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

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.GoogleApiClient.ConnectionCallbacks;

import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;

import com.google.android.gms.location.LocationListener;

import com.google.android.gms.location.LocationRequest;

import com.google.android.gms.location.LocationServices;

import com.google.android.gms.maps.GoogleMap;

import com.google.android.gms.maps.MapFragment;

import com.google.android.gms.maps.OnMapReadyCallback;

import com.google.android.gms.maps.model.LatLng;

import com.google.android.gms.maps.model.MarkerOptions;

public class MapLayoutActivity extends FragmentActivity implements ConnectionCallbacks,

OnConnectionFailedListener, LocationListener {

// LogCat tag

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

private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;

private Location mLastLocation;

// Google client to interact with Google API

private GoogleApiClient mGoogleApiClient;

// boolean flag to toggle periodic location updates

private boolean mRequestingLocationUpdates = false;

private LocationRequest mLocationRequest;

GoogleMap map;

double latitude;

double longitude;

// Location updates intervals in sec

private static int UPDATE_INTERVAL = 10000; // 10 sec

private static int FASTEST_INTERVAL = 5000; // 5 sec

private static int DISPLACEMENT = 10; // 10 meters

// UI elements

private TextView lblLocation;

private Button btnShowLocation, btnStartLocationUpdates;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.map_layout);

map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

// map.addMarker(new MarkerOptions().position(LOCATION_MEHDI).title(“Find me here!”));

// mapFragment.getMapAsync(this);

lblLocation = (TextView) findViewById(R.id.lblLocation);

btnShowLocation = (Button) findViewById(R.id.btnShowLocation);

btnStartLocationUpdates = (Button) findViewById(R.id.btnLocationUpdates);

// First we need to check availability of play services

if (checkPlayServices()) {

// Building the GoogleApi client

buildGoogleApiClient();

createLocationRequest();

}

// Show location button click listener

btnShowLocation.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

displayLocation();

}

});

// Toggling the periodic location updates

btnStartLocationUpdates.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

togglePeriodicLocationUpdates();

}

});

}

@Override

protected void onStart() {

super.onStart();

if (mGoogleApiClient != null) {

mGoogleApiClient.connect();

}

}

@Override

protected void onResume() {

super.onResume();

checkPlayServices();

// Resuming the periodic location updates

if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {

startLocationUpdates();

}

}

@Override

protected void onStop() {

super.onStop();

if (mGoogleApiClient.isConnected()) {

mGoogleApiClient.disconnect();

}

}

@Override

protected void onPause() {

super.onPause();

stopLocationUpdates();

}

/**

* Method to display the location on UI

* */

private void displayLocation() {

mLastLocation = LocationServices.FusedLocationApi

.getLastLocation(mGoogleApiClient);

if (mLastLocation != null) {

latitude = mLastLocation.getLatitude();

longitude = mLastLocation.getLongitude();

lblLocation.setText(latitude + “, ” + longitude);

map.setMapType(GoogleMap.MAP_TYPE_NORMAL);

map.addMarker(new MarkerOptions()

.position(new LatLng(latitude,longitude))

.title(“Marker”));

} else {

lblLocation

.setText(“(Couldn’t get the location. Make sure location is enabled on the device)”);

}

}

/**

* Method to toggle periodic location updates

* */

private void togglePeriodicLocationUpdates() {

if (!mRequestingLocationUpdates) {

// Changing the button text

btnStartLocationUpdates

.setText(getString(R.string.common_google_play_services_network_error_text));

mRequestingLocationUpdates = true;

// Starting the location updates

startLocationUpdates();

Log.d(TAG, “Periodic location updates started!”);

} else {

// Changing the button text

btnStartLocationUpdates

.setText(getString(R.string.common_google_play_services_enable_button));

mRequestingLocationUpdates = false;

// Stopping the location updates

stopLocationUpdates();

Log.d(TAG, “Periodic location updates stopped!”);

}

}

/**

* Creating google api client object

* */

protected synchronized void buildGoogleApiClient() {

mGoogleApiClient = new GoogleApiClient.Builder(this)

.addConnectionCallbacks(this)

.addOnConnectionFailedListener(this)

.addApi(LocationServices.API).build();

}

/**

* Creating location request object

* */

protected void createLocationRequest() {

mLocationRequest = new LocationRequest();

mLocationRequest.setInterval(UPDATE_INTERVAL);

mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

mLocationRequest.setSmallestDisplacement(DISPLACEMENT);

}

/**

* Method to verify google play services on the device

* */

private boolean checkPlayServices() {

int resultCode = GooglePlayServicesUtil

.isGooglePlayServicesAvailable(this);

if (resultCode != ConnectionResult.SUCCESS) {

if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {

GooglePlayServicesUtil.getErrorDialog(resultCode, this,

PLAY_SERVICES_RESOLUTION_REQUEST).show();

} else {

Toast.makeText(getApplicationContext(),

“This device is not supported.”, Toast.LENGTH_LONG)

.show();

finish();

}

return false;

}

return true;

}

/**

* Starting the location updates

* */

protected void startLocationUpdates() {

LocationServices.FusedLocationApi.requestLocationUpdates(

mGoogleApiClient, mLocationRequest, this);

}

/**

* Stopping location updates

*/

protected void stopLocationUpdates() {

LocationServices.FusedLocationApi.removeLocationUpdates(

mGoogleApiClient, this);

}

/**

* Google api callback methods

*/

@Override

public void onConnectionFailed(ConnectionResult result) {

Log.i(TAG, “Connection failed: ConnectionResult.getErrorCode() = ”

+ result.getErrorCode());

}

@Override

public void onConnected(Bundle arg0) {

// Once connected with google api, get the location

displayLocation();

if (mRequestingLocationUpdates) {

startLocationUpdates();

}

}

@Override

public void onConnectionSuspended(int arg0) {

mGoogleApiClient.connect();

}

@Override

public void onLocationChanged(Location location) {

// Assign the new location

mLastLocation = location;

Toast.makeText(getApplicationContext(), “Location changed!”,

Toast.LENGTH_SHORT).show();

// Displaying the new location on UI

displayLocation();

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.menu_map_layout, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// Handle action bar item clicks here. The action bar will

// automatically handle clicks on the Home/Up button, so long

// as you specify a parent activity in AndroidManifest.xml.

int id = item.getItemId();

//noinspection SimplifiableIfStatement

if (id == R.id.action_settings) {

return true;

}

return super.onOptionsItemSelected(item);

}

}

sajid
sajid
5 years ago
Reply to  sajid

using android studio

Arjun
Arjun
5 years ago

What are the different ways to start an activity in android ?

Сергей Попов
Сергей Попов
5 years ago

Code download works?

ToddK
ToddK
5 years ago

Many applications can access this google play services api, and others, is this why when I go to look at battery usage, it shows Google Play Services using more power rather than the applications actually using the service?
p.s. Good tutorial. I liked that it was very detailed in the steps.

Niklas Karlsson
Niklas Karlsson
5 years ago

Cool!, do you know any tutorials for saving a small *very small file with backupmanager, or similar?
(Using: …. )

krikor herlopian
krikor herlopian
5 years ago

first problem is that, this won’t work on certain phones. Second, on this popup GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),

PLAY_SERVICES_RESOLUTION_REQUEST).show(); When I click on get google play services it does nothing on the emulator.Shouldnt it take to some external link

Arjun
Arjun
5 years ago

Hi Ravi,Please Help, Is application data secured in Android ?

Thang
Thang
5 years ago

Thanks Ravi Tamada, your tutorials is great. I have to seen a lots of them, but I wonder why don’t you use Android Studio for simlify import jar/libs?

Aparência Feminina
5 years ago

good work.

Lee
Lee
5 years ago

i tried this but i m not able to see n e thing…it says “Unfortunately LocationApp has stopped”
i was trying to run it on emulator…..what can i do ???
there are no errors ….. help me

Brijesh Thumar
Brijesh Thumar
5 years ago

why you are not use Android Studio ?

Shifar Shifz
5 years ago
Reply to  Brijesh Thumar

Why should he ?
Eclipse is better than AS.

Back Packer
Back Packer
5 years ago
Reply to  Shifar Shifz

No AS is better ! 😀

Viraj
Viraj
5 years ago
Reply to  Shifar Shifz

you probably have not used the stable version..

Wealthy
Wealthy
5 years ago

I ravi Its not working for me or maybe i cant get it to work..are u on skype?

Shifar Shifz
5 years ago

Ravi,I’ve a doubt

CODE 1 :

private static int UPDATE_INTERVAL = 10000;

private static int FATEST_INTERVAL = 5000;

private static int DISPLACEMENT = 10;

CODE 2:

private static int UPDATE_INTERVAL = 10000,

FATEST_INTERVAL = 5000,

DISPLACEMENT = 10;

Does it cause any problem in future if i use CODE2 instead of CODE1 ?

(In brief, What is the problem if we declare variables in a single line if they share the same characteristics ?).

it may be a foolish qstn, don’t laugh.. am a newbie 😉

Ravi Tamada
5 years ago
Reply to  Shifar Shifz

No problem at all. Actually its a good practise too. But I used that way for readability.

Shifar Shifz
5 years ago
Reply to  Ravi Tamada

Ok. 🙂

Guest
Guest
5 years ago
Reply to  Ravi Tamada

Okk.. 🙂

vinod
vinod
5 years ago

hi, all the posts you have given are outstanding…what is the source you are following.. any books,websites or any other stuff?

Pinnochio
5 years ago

Hi Ravi, great tutorials you have here, however, i downloaded the source code imported it to eclipse added all the necessary libraries, but when i run it am having some errors; the logcat shows that “Google play store is missing”,”Google Slay services is invalid. Cannot recover.” What could be the problem.

Mitesh Agrawal
Mitesh Agrawal
5 years ago

Hello Ravi, I tried to run the code but it shows “couldn’t get the location. Make sure location is enabled on the device”. Is it possible to get the location with WIFI/3G/4G connection and gps is turned OFF??

Prathibha Nandini
Prathibha Nandini
5 years ago

Hello Mr.Tamada..I have an app based on your old version code..I have an Issue here..I am tracking a device which is at Hyderabad and in my database I got 2 records of Bhopal & delhi..Do you know why this happened..could you help me in tracking the accurate location please…

Richen Yadav
Richen Yadav
5 years ago

On application launch it gives correct Lat & LOng
but on click START LOCATION UPDATES button
it gives an error — Unfotunatelly,Location Api has Stopped
and application closed

Pinnochio
5 years ago

I posted here this message for help no answer at all……what is the purpose…..of disqus……dissapointed….|”|||||||||||||
Hi Ravi, great tutorials you have here, however, i downloaded the source code imported it to eclipse added all the necessary libraries, but when i run it am having some errors; the logcat shows that “Google play store is missing”,”Google Slay services is invalid. Cannot recover.” What could be the problem

Ravi Tamada
5 years ago
Reply to  Pinnochio

If you are testing on emulator, make sure that you are using > 4.0 version.

Abubaker
Abubaker
5 years ago
Reply to  Ravi Tamada

Hi.. I downloaded the code and tried to run. First it was giving error at AppTheme. removed it and then tried running the app, it is not running. Getting error “AppName stopped unexpectedly”

manvi
manvi
5 years ago

hello sir … this tutorial is awesome …. u r saviour of my job ..
can u please help me that how can i get location of other devices … please sir .. its humble request

Abhishek Patil
Abhishek Patil
5 years ago

Hi ravi, I just modified the displayLocationMethod(), so now we can get the actual name of the place from Current Latitude and Longitude with the help of Geocoder.

/**
* Method to display the location on UI
* */

private void displayLocation() {

mLastLocation = LocationServices.FusedLocationApi

.getLastLocation(mGoogleApiClient);

if (mLastLocation != null) {

double latitude = mLastLocation.getLatitude();

double longitude = mLastLocation.getLongitude();

// lblLocation.setText(latitude + “, ” + longitude);

Geocoder geocoder= new Geocoder(this, Locale.ENGLISH);

try {

//Place your latitude and longitude

List addresses = geocoder.getFromLocation(latitude,longitude, 1);

if(addresses != null) {

Address fetchedAddress = addresses.get(0);

StringBuilder strAddress = new StringBuilder();

for(int i=0; i<fetchedAddress.getMaxAddressLineIndex(); i++)
{

strAddress.append(fetchedAddress.getAddressLine(i)).append("n");

}

lblLocation.setText("You're at: " +strAddress.toString());

}

else{

lblLocation.setText("No location found..!");

}

catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Could not get address..!", Toast.LENGTH_LONG).show();
}

}

else {

lblLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");

}

}

manvi
manvi
5 years ago
Reply to  Abhishek Patil

hello … have u worked by finding location of other persons??

Christian
Christian
5 years ago

Hi Ravi, amazing tutorial, I was wondering why you need to start up other apps with locations (e.g. Google Maps)? Is this not only needed for PRIORITY_NO_POWER ?

Richa Khanna
Richa Khanna
5 years ago

Hey Ravi, I wanted to know why are you calling startLocationUpdate in onResume() when it’s already being called on onConnected? Isn’t startLocationUpdate will be fired when onConnected will be called.

SHON
SHON
5 years ago

Hey when i call startlocationupdate on create it gives me error

google api client is not connected yet
plz help

Deepak
Deepak
5 years ago

hi Ravi..

I am getting this runtime error.

03-29 00:38:40.109: E/AndroidRuntime(25114): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.ni/com.example.ni.MainActivity}: java.lang.ClassNotFoundException: Didn’t find class “com.example.ni.MainActivity” on path: DexPathList[[zip file “/data/app/com.example.ni-2/base.apk”],nativeLibraryDirectories=[/vendor/lib, /system/lib]]

Before adding onConnectionCallBacks, everything worked fine.. after adding this and then running app gave this runtime error.
Plzz help urgently

Arun Bisht
Arun Bisht
5 years ago
Reply to  Deepak

I am facing same issue and searching for 2 days but did not find anything .please suggest some solution if you find

gaurav mangal
gaurav mangal
5 years ago
Reply to  Arun Bisht

Hello Hive Team,

we are facing same problem but i don’t have find a better solution fetch location for resolve bugs for Google play jar please provide and suggest me as soon as possible.

al
al
5 years ago

Hi Ravi, i cann’t download any of ur source after login!!

Ankita Dodia
Ankita Dodia
5 years ago

Hi Ravi,

I saw your Android Location API using Google Play Services example, i try to run this example but i got The import com.google.android.gms.location.LocationServices cannot be resolved error. i m using eclipse and google play service of 17. please reply me how to solve this error.

Arun Bisht
Arun Bisht
5 years ago
Reply to  Ankita Dodia

download latest google-play-services lib from sdk manager. you can see com.google.android.gms.location.LocationServices class by extracting new google-play-services.jar file .

Ankita Dodia
Ankita Dodia
5 years ago
Reply to  Arun Bisht

Hi Arun, Thanks for Reply, can you please tell me that how to update Google play service because my play service version is 17

Arun Bisht
Arun Bisht
5 years ago
Reply to  Ankita Dodia

Hi Ankita, Open sdk manager->Extras->google play services(API 21) -> Install

No game No life
No game No life
5 years ago

Anyone knows any tutorials on making app like this onecomment image

Manaal Maniyar
Manaal Maniyar
5 years ago

Hi Ravi,

I see the app works great when the GPS is on but when GPS is off nothing happened. Is there any way by which we can show user a dialog which would automatically turn GPS ON is GPS is OFF or automatically change GPS setting to HIGH ACCURACY if GPS state is Device only.

I am looking to make it similar to OLACABS android app in which a dialog box comes to ask for user permission if GPS setting is not High accuracy. I think this is standard dialog comes with this API. Can you please help me with this.

Thanks

223
0
Would love your thoughts, please comment.x
()
x