marcco_m marcco_m - 14 days ago 7
Android Question

Is it possible to have multiple GoogleApiClients within one activity?

I'm trying to make a business search app that is location aware. To do this I'm using Google Places Api, specifically Places.GEO_DATA_API and LocationServices.API. The idea is that the user can use their current location or use the autoComplete search to input an address. My problem is that I think the two apis are getting mixed up when calling

onConnected()
since I keep getting this error:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: edu.depaul.csc472.coffeeshoplocator, PID: 9420
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.internal.zzrb.zzb(Unknown Source)
at com.google.android.gms.internal.zzrf.zzb(Unknown Source)
at com.google.android.gms.internal.zzrd.zzb(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at edu.depaul.csc472.coffeeshoplocator.MainActivity.startLocationUpdates(MainActivity.java:233)
at edu.depaul.csc472.coffeeshoplocator.MainActivity.getLocation(MainActivity.java:241)
at edu.depaul.csc472.coffeeshoplocator.MainActivity.onConnected(MainActivity.java:263)
at com.google.android.gms.common.internal.zzk.zzp(Unknown Source)
at com.google.android.gms.internal.zzrd.zzn(Unknown Source)
at com.google.android.gms.internal.zzrb.zzass(Unknown Source)
at com.google.android.gms.internal.zzrb.onConnected(Unknown Source)
at com.google.android.gms.internal.zzrf.onConnected(Unknown Source)
at com.google.android.gms.internal.zzqr.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzj$1.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zze$zzj.zzavj(Unknown Source)
at com.google.android.gms.common.internal.zze$zza.zzc(Unknown Source)
at com.google.android.gms.common.internal.zze$zza.zzv(Unknown Source)
at com.google.android.gms.common.internal.zze$zze.zzavl(Unknown Source)
at com.google.android.gms.common.internal.zze$zzd.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)


It only happens sometimes. I've successfully ran the program without any unexpected behavior except for this crash.

The code for building the apis is the following:

protected synchronized void buildGoogleApiClient(){
mGoogleApiLocation = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiAutoComplete = new GoogleApiClient.Builder(this)
.addApi(Places.GEO_DATA_API)
.enableAutoManage(this,GOOGLE_API_CLIENT_ID,this)
.addConnectionCallbacks(this)
.build();
}


And here is my
onConnected()
method which requests permission to access fine location from the user and then attempts to get the location of the user:

@Override
public void onConnected(Bundle bundle) {
requestForSpecificPermission();
getLocation();
placeArrayAdapter.setGoogleApiClient(mGoogleApiAutoComplete);

}


...and my
getLocation()
method:

private void getLocation(){
try {
location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiLocation);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiLocation, locationRequest, this);
}
else{
handleNewLocation(location);
}
}catch (SecurityException e){
Toast.makeText(getApplicationContext(),
"You don't have permission!", Toast.LENGTH_LONG)
.show();
}
}


My curiosity is one: how am I getting that error if from my understanding you have to be connected to call
onConnected()
and two: why does this only happen some of the times. Is having multiple clients allowed in the first place or if not how do you go about using two different technologies(apis) in the same activity?

Answer

Don't do implements ConnectionCallbacks in your Activity/Fragment and try the following:

GoogleApiClient.ConnectionCallbacks mGoogleApiLocationCallback = new GoogleApiClient.ConnectionCallbacks() {
        @Override
        public void onConnected(@Nullable Bundle bundle) {

        }

        @Override
        public void onConnectionSuspended(int i) {

        }
    };

    GoogleApiClient.ConnectionCallbacks mGoogleApiAutoCompleteCallback = new GoogleApiClient.ConnectionCallbacks() {
        @Override
        public void onConnected(@Nullable Bundle bundle) {

        }

        @Override
        public void onConnectionSuspended(int i) {

        }
    };

And then change your method like this:

protected synchronized void buildGoogleApiClient(){
    mGoogleApiLocation = new GoogleApiClient.Builder(context)
            .addConnectionCallbacks(mGoogleApiLocationCallback)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiAutoComplete = new GoogleApiClient.Builder(context)
            .addConnectionCallbacks(mGoogleApiAutoCompleteCallback)
            .addApi(Places.GEO_DATA_API)
            .enableAutoManage(this,GOOGLE_API_CLIENT_ID,this)
            .build();
}

Just make sure to remove implements GoogleApiClient.ConnectionCallbacks from your Activity/Fragment