Annyce Davis

ones and zeros

  • Home
  • Public Speaking
  • About Me
  • Courses
  • Life

Android: Location Updates with the FusedLocationApi

September 30, 2014 by Annyce Davis Leave a Comment

If you want to retrieve the user’s location in your Android application you can take advantage of Google’s FusedLocationApi. Essentially you establish a connection to the GoogleApiClient and then set up a LocationRequest.  It’s up to you to configure the rate at which you would like to receive updates.  Here is an example of using the API:

import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;

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.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

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

private static final long ONE_MIN = 1000 * 60;
private static final long TWO_MIN = ONE_MIN * 2;
private static final long FIVE_MIN = ONE_MIN * 5;
private static final long POLLING_FREQ = 1000 * 30;
private static final long FASTEST_UPDATE_FREQ = 1000 * 5;
private static final float MIN_ACCURACY = 25.0f;
private static final float MIN_LAST_READ_ACCURACY = 500.0f;

private LocationRequest mLocationRequest;
private Location mBestReading;

private GoogleApiClient mGoogleApiClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (!servicesAvailable()) {
finish();
}

setContentView(R.layout.activity_main);

mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(POLLING_FREQ);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_FREQ);

mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}

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

if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}

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

if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}

@Override
public void onLocationChanged(Location location) {
// Determine whether new location is better than current best
// estimate
if (null == mBestReading || location.getAccuracy() < mBestReading.getAccuracy()) {
mBestReading = location;

if (mBestReading.getAccuracy() < MIN_ACCURACY) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
}

@Override
public void onConnected(Bundle dataBundle) {
// Get first reading. Get additional location updates if necessary
if (servicesAvailable()) {
// Get best last location measurement meeting criteria
mBestReading = bestLastKnownLocation(MIN_LAST_READ_ACCURACY, FIVE_MIN);

if (null == mBestReading
|| mBestReading.getAccuracy() > MIN_LAST_READ_ACCURACY
|| mBestReading.getTime() < System.currentTimeMillis() - TWO_MIN) {

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

// Schedule a runnable to unregister location listeners
Executors.newScheduledThreadPool(1).schedule(new Runnable() {

@Override
public void run() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, MainActivity.this);
}

}, ONE_MIN, TimeUnit.MILLISECONDS);
}
}
}

@Override
public void onConnectionSuspended(int i) {

}

private Location bestLastKnownLocation(float minAccuracy, long minTime) {
Location bestResult = null;
float bestAccuracy = Float.MAX_VALUE;
long bestTime = Long.MIN_VALUE;

// Get the best most recent location currently available
Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

if (mCurrentLocation != null) {
float accuracy = mCurrentLocation.getAccuracy();
long time = mCurrentLocation.getTime();

if (accuracy < bestAccuracy) {
bestResult = mCurrentLocation;
bestAccuracy = accuracy;
bestTime = time;
}
}

// Return best reading or null
if (bestAccuracy > minAccuracy || bestTime < minTime) {
return null;
}
else {
return bestResult;
}
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

private boolean servicesAvailable() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

if (ConnectionResult.SUCCESS == resultCode) {
return true;
}
else {
GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0).show();
return false;
}
}
}

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)

Related

Filed Under: Android Tagged With: FusedLocationApi, GoogleApiClient, Location

Follow Me

What engineering leaders need to know from this year’s Google I/O

I didn't intentionally aim to create a rhyming title, but there you have it. Each year, I look forward to Google I/O like a kid going back to school. This year … [Read More...]

Talk: The Real MVP

You have an idea for a new app. You've secured buy-in from the business. What's next? The MVP. But what does it take to ship a new app these days? What are the … [Read More...]

Categories

  • Android (55)
  • Career (2)
  • Communication (4)
  • Flutter (1)
  • Git (4)
  • Gradle (4)
  • Grails (23)
  • Java (8)
  • JavaScript (6)
  • Kotlin (17)
  • Life (4)
  • Public Speaking (23)
  • RxJava (1)
  • Software Development (7)
  • Twitter (3)
  • Uncategorized (11)
  • Video Course (5)

Copyright © 2023 · Beautiful Pro Theme on Genesis Framework · WordPress · Log in