Updated Location Service to use Google Play Location Service
This commit is contained in:
@@ -72,6 +72,8 @@ public final class LocationLibraryConstants {
|
||||
|
||||
public static final String INTENT_EXTRA_LOCATION_CHANGED = LocationManager.KEY_LOCATION_CHANGED;
|
||||
|
||||
public static final String INTENT_EXTRA_LOCATION_ATUO = "RockBarrette.action.LocationAuto";
|
||||
|
||||
/**
|
||||
* Used to tell the service how accurate of a location you want reported
|
||||
*/
|
||||
@@ -82,4 +84,15 @@ public final class LocationLibraryConstants {
|
||||
* no data
|
||||
*/
|
||||
public static final long FAIL_SAFE_UPDATE_INVERVAL = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
|
||||
|
||||
// Milliseconds per second
|
||||
private static final int MILLISECONDS_PER_SECOND = 1000;
|
||||
// Update frequency in seconds
|
||||
private static final int UPDATE_INTERVAL_IN_SECONDS = 30;
|
||||
// Update frequency in milliseconds
|
||||
public static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
|
||||
// The fastest update frequency, in seconds
|
||||
private static final int FASTEST_INTERVAL_IN_SECONDS = 30;
|
||||
// A fast frequency ceiling in milliseconds
|
||||
public static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
|
||||
}
|
||||
@@ -133,9 +133,7 @@ public class GeoUtils {
|
||||
*
|
||||
* we are solving this equation for lon2Rad
|
||||
*
|
||||
* lon2Rad =
|
||||
* lon1Rad+acos(cos(meters/6371)sec(lat1Rad)sec(lat2Rad)-tan(lat1Rad
|
||||
* )tan(lat2Rad))
|
||||
* lon2Rad = lon1Rad+acos(cos(meters/6371)sec(lat1Rad)sec(lat2Rad)-tan(lat1Rad)tan(lat2Rad))
|
||||
*
|
||||
* NOTE: sec(x) = 1/cos(x)
|
||||
*
|
||||
@@ -148,10 +146,35 @@ public class GeoUtils {
|
||||
* device, and the distanceKm() from google and has been proven to be
|
||||
* damn close
|
||||
*/
|
||||
final double lon2Rad = lon1Rad + Math.acos(Math.cos(distance / 6371) * (1 / Math.cos(lat1Rad)) * (1 / Math.cos(lat1Rad)) - Math.tan(lat1Rad) * Math.tan(lat1Rad));
|
||||
final double lon2Rad = lon1Rad + Math.acos(Math.cos(distance / 6371) * sec(lat1Rad) * sec(lat1Rad) - Math.tan(lat1Rad) * Math.tan(lat1Rad));
|
||||
|
||||
// return a LatLng that is x meters away from the LatLng supplied
|
||||
return new LatLng(point.latitude, (int) (Math.toDegrees(lon2Rad) * 1e6));
|
||||
return new LatLng(point.latitude, Math.toDegrees(lon2Rad));
|
||||
}
|
||||
|
||||
public static LatLng distanceFrom(final LatLng point, final double distance, final float bearing) {
|
||||
final double dist = distance / 6371;
|
||||
final double brng = Math.toRadians(bearing);
|
||||
|
||||
final double lat1 = Math.toRadians(point.latitude);
|
||||
final double lon1 = Math.toRadians(point.longitude);
|
||||
|
||||
final double lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) + Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));
|
||||
|
||||
final double lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) * Math.cos(lat1), Math.cos(dist) - Math.sin(lat1) * Math.sin(lat2));
|
||||
|
||||
// if (isNaN(lat2) || isNaN(lon2))
|
||||
// return null;
|
||||
return new LatLng(Math.toDegrees(lat2), Math.toDegrees(lon2));
|
||||
}
|
||||
|
||||
/**
|
||||
* compute secant
|
||||
* @param theta angle in radians
|
||||
* @return secant of theta.
|
||||
*/
|
||||
public static double sec ( double theta ){
|
||||
return 1.0 / Math.cos( theta );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,16 +25,17 @@ import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.os.*;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.util.Log;
|
||||
|
||||
import com.TwentyCodes.android.debug.Debug;
|
||||
import com.TwentyCodes.android.debug.LocationLibraryConstants;
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GooglePlayServicesClient;
|
||||
import com.google.android.gms.common.GooglePlayServicesUtil;
|
||||
import com.google.android.gms.location.LocationClient;
|
||||
import com.google.android.gms.location.LocationListener;
|
||||
import com.google.android.gms.location.LocationRequest;
|
||||
|
||||
/**
|
||||
* This service class will be used broadcast the users location either one time,
|
||||
@@ -42,10 +43,21 @@ import com.TwentyCodes.android.debug.LocationLibraryConstants;
|
||||
*
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class LocationService extends Service implements LocationListener {
|
||||
public class LocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
|
||||
|
||||
public static final String TAG = "LocationService";
|
||||
private static final int REQUEST_CODE = 7893749;
|
||||
private IBinder mBinder;
|
||||
private LocationClient mLocationClient;
|
||||
private LocationRequest mLocationRequest;
|
||||
// Flag that indicates if a request is underway.
|
||||
private boolean mInProgress;
|
||||
private Boolean servicesAvailable = false;
|
||||
private WakeLock mWakeLock;
|
||||
private Location mLocation;
|
||||
private int mStartId;
|
||||
private int mRequiredAccuracy;
|
||||
private Intent mIntent;
|
||||
|
||||
/**
|
||||
* a convince method for getting an intent to start the service
|
||||
@@ -76,14 +88,6 @@ public class LocationService extends Service implements LocationListener {
|
||||
};
|
||||
}
|
||||
|
||||
private WakeLock mWakeLock;
|
||||
private Location mLocation;
|
||||
private int mStartId;
|
||||
private AndroidGPS mLocationManager;
|
||||
private int mRequiredAccuracy;
|
||||
|
||||
private Intent mIntent;
|
||||
|
||||
/*
|
||||
* this runnable will be qued when the service is created. this will be used
|
||||
* as a fail safe
|
||||
@@ -116,20 +120,6 @@ public class LocationService extends Service implements LocationListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see android.app.Service#onBind(android.content.Intent)
|
||||
* @param arg0
|
||||
* @return
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(final Intent arg0) {
|
||||
// UNUSED
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* called when the service is created. this will initialize the location
|
||||
* manager, and acquire a wakelock (non-Javadoc)
|
||||
@@ -139,7 +129,6 @@ public class LocationService extends Service implements LocationListener {
|
||||
*/
|
||||
@Override
|
||||
public void onCreate() {
|
||||
mLocationManager = new AndroidGPS(this);
|
||||
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||
mWakeLock.acquire();
|
||||
@@ -150,6 +139,24 @@ public class LocationService extends Service implements LocationListener {
|
||||
*/
|
||||
new Handler().postDelayed(failSafe, LocationLibraryConstants.MAX_LOCATION_SERVICE_RUN_TIME);
|
||||
super.onCreate();
|
||||
|
||||
mInProgress = false;
|
||||
// Create the LocationRequest object
|
||||
mLocationRequest = LocationRequest.create();
|
||||
// Use high accuracy
|
||||
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
|
||||
// Set the update interval to 5 seconds
|
||||
mLocationRequest.setInterval(LocationLibraryConstants.UPDATE_INTERVAL);
|
||||
// Set the fastest update interval to 1 second
|
||||
mLocationRequest.setFastestInterval(LocationLibraryConstants.FASTEST_INTERVAL);
|
||||
|
||||
servicesAvailable = servicesConnected();
|
||||
|
||||
/*
|
||||
* Create a new location client, using the enclosing class to
|
||||
* handle callbacks.
|
||||
*/
|
||||
mLocationClient = new LocationClient(this, this, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,7 +169,15 @@ public class LocationService extends Service implements LocationListener {
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
broadcastLocation();
|
||||
mLocationManager.disableLocationUpdates();
|
||||
|
||||
// Turn off the request flag
|
||||
mInProgress = false;
|
||||
if(servicesAvailable && mLocationClient != null) {
|
||||
// Destroy the current location client
|
||||
mLocationClient.removeLocationUpdates(this);
|
||||
mLocationClient = null;
|
||||
}
|
||||
|
||||
if (mWakeLock.isHeld())
|
||||
mWakeLock.release();
|
||||
}
|
||||
@@ -177,18 +192,6 @@ public class LocationService extends Service implements LocationListener {
|
||||
stopSelf(mStartId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(final String provider) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(final String provider) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when startService is called. only used in 2.x
|
||||
* android.
|
||||
@@ -203,13 +206,19 @@ public class LocationService extends Service implements LocationListener {
|
||||
|
||||
parseIntent(intent);
|
||||
|
||||
mLocationManager.enableLocationUpdates(this);
|
||||
super.onStartCommand(intent, flags, startId);
|
||||
|
||||
if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
|
||||
return START_STICKY;
|
||||
|
||||
setUpLocationClientIfNeeded();
|
||||
if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress)
|
||||
{
|
||||
mInProgress = true;
|
||||
mLocationClient.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(final String provider, final int status, final Bundle extras) {
|
||||
// TODO Auto-generated method stub
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,4 +237,86 @@ public class LocationService extends Service implements LocationListener {
|
||||
mRequiredAccuracy = intent.getIntExtra(LocationLibraryConstants.INTENT_EXTRA_REQUIRED_ACCURACY, LocationLibraryConstants.MINIMUM_REQUIRED_ACCURACY);
|
||||
}
|
||||
}
|
||||
|
||||
public class LocalBinder extends Binder {
|
||||
public LocationService getServerInstance() {
|
||||
return LocationService.this;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean servicesConnected() {
|
||||
|
||||
// Check that Google Play services is available
|
||||
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
|
||||
|
||||
// If Google Play services is available
|
||||
if (ConnectionResult.SUCCESS == resultCode) {
|
||||
|
||||
return true;
|
||||
} else {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new location client, using the enclosing class to
|
||||
* handle callbacks.
|
||||
*/
|
||||
private void setUpLocationClientIfNeeded()
|
||||
{
|
||||
if(mLocationClient == null)
|
||||
mLocationClient = new LocationClient(this, this, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by Location Services when the request to connect the
|
||||
* client finishes successfully. At this point, you can
|
||||
* request the current location or start periodic updates
|
||||
*/
|
||||
@Override
|
||||
public void onConnected(Bundle bundle) {
|
||||
|
||||
mLocationClient.requestLocationUpdates(mLocationRequest, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by Location Services if the connection to the
|
||||
* location client drops because of an error.
|
||||
*/
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
// Turn off the request flag
|
||||
mInProgress = false;
|
||||
mLocationClient.removeLocationUpdates(this);
|
||||
// Destroy the current location client
|
||||
mLocationClient = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by Location Services if the attempt to
|
||||
* Location Services fails.
|
||||
*/
|
||||
@Override
|
||||
public void onConnectionFailed(ConnectionResult connectionResult) {
|
||||
mInProgress = false;
|
||||
|
||||
/*
|
||||
* Google Play services can resolve some errors it detects.
|
||||
* If the error has a resolution, try sending an Intent to
|
||||
* start a Google Play services activity that can resolve
|
||||
* error.
|
||||
*/
|
||||
if (connectionResult.hasResolution()) {
|
||||
|
||||
// If no resolution is available, display an error dialog
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user