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.
<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.
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.
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: ravi@androidhive.info
Excellent Ravi, usefull tutorial
thanks Ravi for this nice tutorial
Works perfectly, thank you Ravi 🙂
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!
Hi Paresh,
LocationClient is deprecated, but not LocationRequest. When did LocationRequest class become deprecated. 😛
Ohh yeah….that’s my mistake! I was talking about LocationClient only.
Got it. Let me check that … thanx 🙂
🙂
Any chance of future tutorial using Android Studio as the IDE?
Great tutorial …..brother …please make a weather app tutorial brother
Why not Android Studio? Anyway! Still a great tutorial. Cheers!
I do use Android Studio. But I have to write a tutorial about AS first before publishing my articles using AS.
I see. That’s pretty good. Start on basic to avoid confusion using the new IDE. Cheers!
Well said 🙂
Yes , waiting for Android Studio tutorial.
Same here waiting for Android Studio Tutorials. Thanks Loads Ravi.
yes! please start creating tag for android studio and it has come to beta version ! i hope! @Ravi Tamada:disqus
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
Check your internet connection.
It is connnected
Actually i use same tutorial for ADT and it’s working fine
Got it man. Thanks a ton
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
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 😀 !!
which devices and APIs that works on ?
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.
Gr8! Thx for it! Could you recommend a good geofencing tutorial?
Try playing with this project.
http://developer.android.com/shareables/training/GeofenceDetection.zip
i am facing error in this tutorial
it shows jar mismatch fix project dependencies how can i solve this
my problem???
Try to replace the android-support-v4.jar with the jar that found in appcompat_v7 libs folder.
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?
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().
Thank you vinay. Corrected now.
(Y)
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
Excellent Ravi, usefull tutorial, but i face problems to import import com.google.android.gms.location.LocationServices;.
please help me…..:)
Did you added Google Play Services as library project?
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?
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?
Remove the casting, verify the import statements at the top.
Nice tutorial …. Which emulator you used in this tutorial bro?
Its a device bro. I used nexus5 to record the screen and then edited the video placing it on a mobile png image.
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
😀
This might helps you
http://stackoverflow.com/questions/1006654/fastest-way-to-find-distance-between-two-lat-long-points
hi Ravi, I got this problem on
import com.google.android.gms.location.LocationServices;
it seems can’t be fix using Fix Project Setup..
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
Is your device connected to internet?
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);
}
}
using android studio
What are the different ways to start an activity in android ?
Code download works?
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.
Cool!, do you know any tutorials for saving a small *very small file with backupmanager, or similar?
(Using: …. )
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
Hi Ravi,Please Help, Is application data secured in Android ?
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?
good work.
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
why you are not use Android Studio ?
Why should he ?
Eclipse is better than AS.
No AS is better ! 😀
you probably have not used the stable version..
I ravi Its not working for me or maybe i cant get it to work..are u on skype?
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 😉
No problem at all. Actually its a good practise too. But I used that way for readability.
Ok. 🙂
Okk.. 🙂
hi, all the posts you have given are outstanding…what is the source you are following.. any books,websites or any other stuff?
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.
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??
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…
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
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
If you are testing on emulator, make sure that you are using > 4.0 version.
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”
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
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)");
}
}
hello … have u worked by finding location of other persons??
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 ?
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.
Hey when i call startlocationupdate on create it gives me error
google api client is not connected yet
plz help
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
I am facing same issue and searching for 2 days but did not find anything .please suggest some solution if you find
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.
Hi Ravi, i cann’t download any of ur source after login!!
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.
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 .
Hi Arun, Thanks for Reply, can you please tell me that how to update Google play service because my play service version is 17
Hi Ankita, Open sdk manager->Extras->google play services(API 21) -> Install
Anyone knows any tutorials on making app like this one
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