This is what I've used in the past, it works pretty well for me:
public class LocationService
extends Service implements GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private LocationReceiver locationReceiver = new LocationReceiver();
public LocationClient locationClient;
public LocationRequest locationRequest;
private Location previous;
String TAG = "LocationService";
private boolean monitorLocation;
private boolean googleServicesAvailable = false;
@Override
public void onCreate() {
super.onCreate();
this.monitorLocation = false;
//this.locationListener = new LocationListener();
this.locationRequest = LocationRequest.create();
this.locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); // Use high accuracy
this.locationRequest.setInterval(Singletons.Location.regularIntervalTime); // Setting the update interval to 5mins
this.locationRequest.setFastestInterval(Singletons.Location.fastIntervalTime); // Set the fastest update interval to 1 min
this.googleServicesAvailable = servicesConnected();
this.locationClient = new LocationClient(this, this, this);
}
public boolean servicesConnected() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode == ConnectionResult.SUCCESS) {
//Log.d(TAG, "LocationService: Location services available");
return true;
} else {
Log.e(TAG, "Location services not available");
return false;
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (!this.googleServicesAvailable || this.locationClient.isConnected() || this.monitorLocation) {
//Log.d(TAG, "LocationService: services already started");
return START_STICKY;
}
setUpLocationClientIfNeeded();
if (!this.locationClient.isConnected() || !this.locationClient.isConnecting() && !this.monitorLocation) {
//Log.d(TAG, "LocationService: service is starting now");
this.monitorLocation = true;
this.locationClient.connect();
}
return Service.START_STICKY;
}
public void setUpLocationClientIfNeeded() {
if (this.locationClient == null) {
this.locationClient = new LocationClient(this, this, this);
}
}
@Override
public void onLocationChanged(Location location) {
if (this.previous == null) {
this.previous = location;
}
if (!this.isSameLocation(location, this.previous)) {
LocationDataSource datasource = new LocationDataSource(getApplicationContext());
datasource.open();
datasource.insertNewLocation(location, this.previous);
datasource.close();
this.previous = location;
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onConnected(Bundle bundle) {
this.locationClient.requestLocationUpdates(this.locationRequest, this);
}
@Override
public void onDisconnected() {
this.monitorLocation = false;
this.locationClient = null;
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
this.monitorLocation = false;
if (connectionResult.hasResolution()) {
Log.d(TAG, "LocationService: We can resolve the problem?");
// If no resolution is available, display an error dialog
} else {
Log.e(TAG, "LocationService: We cannot resolve the gms location problem");
}
}
@Override
public void onDestroy() {
// Turn off the request flag
this.monitorLocation = false;
if (this.googleServicesAvailable && this.locationClient != null) {
//this.locationClient.removeLocationUpdates(this);
// Destroy the current location client
this.locationClient = null;
}
super.onDestroy();
}
public boolean isSameLocation(Location l, Location p) {
return (p.getLongitude() == l.getLongitude()) && (p.getLatitude() == l.getLatitude());
}
}