Google API client error sending addresses
I want to create that I send a message every few seconds to GCM. But after a while, I want to delete locationupdates again. I am using pendingintent to send data to intenservice gcm. Now every time, and this happens a lot, I get this error:
Caused by:
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.internal.n.a(Unknown Source)
at com.google.android.gms.common.api.b.b(Unknown Source)
at com.google.android.gms.internal.lt.removeLocationUpdates(Unknown Source)
at com.example.task_1.Location.LocationUpdate.stopLocationUpdates(LocationUpdate.java:83)
at com.example.task_1.Location.LocationUpdate.onStartCommand(LocationUpdate.java:52)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2704)
at android.app.ActivityThread.access$1900(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1353)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
This is my code:
public class LocationUpdate extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "DRIVER";
private SharedPreferences pref;
private String driverId;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Intent mGcmIntentService;
private PendingIntent mPendingIntent;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
boolean stopService = false;
if (intent != null)
stopService = intent.getBooleanExtra("stopservice", false);
if (stopService)
stopLocationUpdates();
return START_STICKY;
}
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
pref = getSharedPreferences("driver_app", MODE_PRIVATE);
driverId = pref.getString("driver_id", "");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
}
public void stopLocationUpdates() {
if(!mGoogleApiClient.isConnected()){
mGoogleApiClient.connect();
}
mGcmIntentService = new Intent(this,SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
if (mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
@Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
@Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(30000);
startLocationUpdates();
}
private void startLocationUpdates() {
mGcmIntentService = new Intent(this,SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
}
@Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
}
Does anyone know how to resolve this error? Or how to fix it? I have searched on the internet but found nothing.
The problem is that in your method, stopLocationUpdates()
you don't expect the API to be connected before you call removeLocationUpdates()
.
One easy way to fix this is to set a boolean flag when you need to remove location callbacks but the API is not connected.
Add a member variable:
private boolean isRemoving = false;
Then change the logic so that it expects the API to connect before unregistering for location callbacks.
In the method stopLocationUpdates()
:
public void stopLocationUpdates() {
if(!mGoogleApiClient.isConnected()){
isRemoving = true; //added
mGoogleApiClient.connect();
}
else {
mGcmIntentService = new Intent(this, SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
if (mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
}
In the callback onConnected()
:
@Override
public void onConnected(Bundle arg0) {
if (isRemoving){
stopLocationUpdates();
}
else {
// TODO Auto-generated method stub
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(30000);
startLocationUpdates();
}
}
You would also like to set the flag to false in startLocationUpdates()
:
private void startLocationUpdates() {
isRemoving = false; //added
mGcmIntentService = new Intent(this,SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
}
Also in onCreate()
:
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
isRemoving = false; //added
pref = getSharedPreferences("driver_app", MODE_PRIVATE);
driverId = pref.getString("driver_id", "");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
}
Edit: To rerun the location callbacks after canceling them, you can use the method onStartCommand()
.
Change onStartCommand()
so it can stop and start updating the location:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
boolean stopService = false;
if (intent != null) {
stopService = intent.getBooleanExtra("stopservice", false);
}
if (stopService) {
stopLocationUpdates();
}
else{
isRemoving = false;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
}
return START_STICKY;
}
Then, to re-install the location updates, you call startService()
with an intent that is stopservice
set to false:
Intent i = new Intent(this, LocationUpdate.class);
i.putExtra("stopservice", false);
startService(i);