I am trying to listen to location changes but sometimes onLocationChanged
callback is never called and getLastLocation
returns null
, while Google Maps always working perfectly.
Note
If I reboot my device the location service will work for ~2 days only; after that neither my app nor the SDK example will work while Google Maps still working.
This is my service code:
public class VisitService extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener {
private final IBinder mBinder = new VisitBinder();
// A request to connect to Location Services
private LocationRequest mLocationRequest;
// Stores the current instantiation of the location client in this object
private LocationClient mLocationClient;
private boolean mLocationServiceConnected = false;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
initLocation();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
initLocation();
return mBinder;
}
public void startVisit() {
if (!servicesConnected()) {
listener.onVisitStartError();
return;
}
if (mLocationServiceConnected) {
if (isAcceptableLocation(mLocationClient.getLastLocation())) {
Toast.makeText(this, "You have arrived!", Toast.LENGTH_LONG);
} else {
mVisitListener.onVisitStartError();
}
}
}
private boolean isAcceptableLocation(Location location) {
if (location == null) {
Toast.makeText(this, "Location is null", Toast.LENGTH_LONG).show();
return false;
}
return true;
}
private void initLocation() {
if (mLocationRequest == null) {
// Create a new global location parameters object
mLocationRequest = LocationRequest.create();
/*
* Set the update interval
*/
mLocationRequest
.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
// Use high accuracy
mLocationRequest
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the interval ceiling to one minute
mLocationRequest
.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
}
if (mLocationClient == null) {
mLocationClient = new LocationClient(this, this, this);
mLocationClient.connect();
}
}
/**
* Verify that Google Play services is available before making a request.
*
* @return true if Google Play services is available, otherwise false
*/
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) {
// In debug mode, log the status
Log.d(LocationUtils.APPTAG,
getString(R.string.play_services_available));
return true;
} else {
return false;
}
}
public class VisitBinder extends Binder {
public VisitService getService() {
return VisitService.this;
}
}
/**
* In response to a request to start updates, send a request to Location
* Services
*/
private void startPeriodicUpdates() {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
Toast.makeText(this, "Location Update Requested", Toast.LENGTH_LONG).show();
}
/**
* In response to a request to stop updates, send a request to Location
* Services
*/
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(LocationUtils.APPTAG, "Location Services Connection faild");
}
@Override
public void onConnected(Bundle bundle) {
Log.d(LocationUtils.APPTAG, "Location Services Connected");
mLocationServiceConnected = true;
startPeriodicUpdates();
}
@Override
public void onDisconnected() {
mLocationServiceConnected = false;
}
@Override
public void onLocationChanged(Location location) {
Toast.makeText(this, "Location has been changed", Toast.LENGTH_LONG).show();
}
}
Android Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>