Fatal Exception: java.lang.IllegalStateException GoogleApiClient is not connected yet
Asked Answered
M

3

20

We have this crash in crashlytics, the weird thing is it happens in onConnected() callback when requesting location updates.

Code:

abstract public class MainService_6_LocationClient extends MainService_5_DriverGpsLocationStoring
    implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {


  private LocationListener highAccuracyListener;
  private GoogleApiClient googleApiClient;
  private LocationRequest gpsRequest;

  @Override
  public void onCreate() {
    super.onCreate();
    lazyInit();
    googleApiClient.connect();
  }

  @Override public void onConnected(Bundle bundle) {
    Log.d(TAG, "onConnected");
    lazyInit();
    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, gpsRequest,
          highAccuracyListener);
  }

  private void lazyInit() {

    if (highAccuracyListener == null) {
      highAccuracyListener = new HighAccuracyLocationListener();
    }

    if (googleApiClient == null) {
      googleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API)
          .addConnectionCallbacks(this)
          .addOnConnectionFailedListener(this)
          .build();
    }

    if (gpsRequest == null) {
      gpsRequest = new LocationRequest().setInterval(2000)
          .setFastestInterval(1000)
          .setSmallestDisplacement(0)
          .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }
  }

  @Override public void onConnectionSuspended(int i) {
    Log.w(TAG, "onConnectionSuspended");
    lazyInit();
    googleApiClient.reconnect();
  }

  @Override public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.e(TAG, "onConnectionFailed");
  }

  @Override public void onDestroy() {
    Log.d(TAG, "onDestroy");

    if (googleApiClient != null) {
      if (googleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient,
            highAccuracyListener);
        googleApiClient.disconnect();
      }

      googleApiClient = null;
    }
    highAccuracyListener = null;
    gpsRequest = null;

    super.onDestroy();
  }

Crash log:

java.lang.IllegalStateException: GoogleApiClient is not connected yet.
       at com.google.android.gms.common.internal.o.a()
       at com.google.android.gms.common.api.b.b()
       at com.google.android.gms.internal.lu.requestLocationUpdates()
       at ee.mtakso.driver.service.orderState.MainService_6_LocationClient.onConnected(MainService_6_LocationClient.java:33)
       at com.google.android.gms.common.internal.f.d()
       at com.google.android.gms.common.api.b.gm()
       at com.google.android.gms.common.api.b.d()
       at com.google.android.gms.common.api.b$2.onConnected()
       at com.google.android.gms.common.internal.f.d()
       at com.google.android.gms.common.internal.f.dL()
       at com.google.android.gms.common.internal.e$h.b()
       at com.google.android.gms.common.internal.e$h.g()
       at com.google.android.gms.common.internal.e$b.gU()
       at com.google.android.gms.common.internal.e$a.handleMessage()
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4947)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
       at dalvik.system.NativeStart.main(NativeStart.java)

Doesn't onConnected() imply GoogleApiClient is connected and ready to be used? How can I resolve this?

Masera answered 18/11, 2014 at 15:44 Comment(2)
Did you ever resolve this problem? I am seeing a similar occurrence in an emulator.Retrusion
@Retrusion I got answer https://mcmap.net/q/270717/-quot-googleapiclient-is-not-connected-yet-quot-exception-in-cast-applicationPugnacious
P
9

https://developer.android.com/reference/com/google/android/gms/common/api/GoogleApiClient.html

You should instantiate a client object in your Activity's onCreate(Bundle) method and then call connect() in onStart() and disconnect() in onStop(), regardless of the state.

The implementation of the GoogleApiClient appears designed for only a single instance. It's best to instantiate it only once in onCreate, then perform connections and disconnections using the single instance.

Prediction answered 8/5, 2015 at 20:35 Comment(0)
V
1

Maybe you should notice, GoogleApiClient.Builder has a method setAccountName(). You should invoke this method with your Google account name. I have tried, and succeeded. I used the following code:

if (mGoogleApiClient == null) {
    mGoogleApiClient = new GoogleApiClient.Builder(context)
       .addApi(LocationServices.API)
       .addConnectionCallbacks(this)
       .addOnConnectionFailedListener(this)
       .setAccountName("李江涛")
       .build();
}

if (mLocationRequest == null) {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
Vallo answered 5/10, 2015 at 10:45 Comment(1)
"your" account name doesn't matter. If you want to specify an account it hast to be on the user's device. You usually don't specify this because the user has to have a Google account to use play services on his device. This default account will be used if you don't set anything.Osburn
P
-1

Try using com.google.android.gms.location.LocationClient instead of GoogleApiClient. Note that the ConnectionCallbacks and OnConnectionFailedListener interfaces that you implement will be slightly different.

Here's a quick example:

class LocationHandler implements ConnectionCallbacks,
        OnConnectionFailedListener, LocationListener {

    private LocationClient client;

    void getLocation(Context context) {
        client = new LocationClient(context, this, this);
        client.connect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        LocationRequest request = LocationRequest.create();
        request.setNumUpdates(1);
        client.requestLocationUpdates(request, this);
        client.unregisterConnectionCallbacks(this);
    }

    @Override
    public void onDisconnected() { }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // handle connection failure
    }

    @Override
    public void onLocationChanged(Location location) {
        client.removeLocationUpdates(this);
        client.disconnect();

        // do stuff with the location
    }

}
Pot answered 19/11, 2014 at 20:1 Comment(2)
GoogleApiClient is the de facto api for location services nowadays.Retrusion
Yep, it appears that LocationClient has been removed altogether. At the time (and maybe this is still the case) the location services documentation still showed examples with LocationClient. Looks like I fell victim to the same problem as these people.Pot

© 2022 - 2024 — McMap. All rights reserved.