致命异常:java.lang.IllegalStateException,GoogleApiClient尚未连接

20

我们在Crashlytics中发现了这个崩溃,奇怪的是它发生在请求位置更新时的onConnected()回调函数中。

代码:

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();
  }

崩溃日志:

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)

onConnected()不意味着GoogleApiClient已连接并准备好使用吗?我该如何解决这个问题?


1
你解决过这个问题吗?我在模拟器中遇到了类似的情况。 - IgorGanapolsky
1
@IgorGanapolsky 我得到了答案 https://dev59.com/nGEh5IYBdhLWcg3w9Xen#31691878 - Pratik Butani
3个回答

9

1

也许你应该注意到,GoogleApiClient.Builder有一个setAccountName()方法。你需要使用你的Google帐户名称调用此方法。我尝试过,并成功了。我使用了以下代码:

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);
}

您的账户名称并不重要。如果您想指定一个账户,它必须在用户设备上。通常情况下您不需要指定,因为用户必须拥有一个Google账户才能在他的设备上使用Play服务。如果您什么都没有设置,将会使用默认账户。 - The incredible Jan

-1

尝试使用com.google.android.gms.location.LocationClient代替GoogleApiClient。请注意,您实现的ConnectionCallbacksOnConnectionFailedListener接口将略有不同。

这里是一个快速示例:

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
    }

}

GoogleApiClient是当今定位服务的事实API。 - IgorGanapolsky
3
看起来LocationClient已经被完全移除了。当时(也许现在仍然如此),位置服务文档仍显示使用LocationClient的示例。看起来我遭遇了与这些人相同的问题。 - Craig McIlwee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接