0

I'm building a simple map application using the Google Maps API. When I open the app it will sometimes crash because the GoogleApiClient is not connected yet. I have a few methods that run and need the API to be connected.

How do I prevent the crashes by waiting for the API to connect?

Here is some of my code: onConnected:

@Override
public void onConnected(Bundle connectionHint)
{
    // this callback will be invoked when all specified services are connected
    //Must ask for explicit permission
    //ie: Opening settings action in order to change or give permissions
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        currentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleClient);
        mGoogleClient.connect();

        if (currentLocation != null)
        { 
            currentLatLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15));
        } 

        else
        {
           if (mGoogleClient!=null )
           {
               mGoogleClient.connect();
           }

            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleClient, locationRequest, this);

        }
    }
}

Getting the current location:

private void getLocation() {

    locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(60 * 1000);
    locationRequest.setFastestInterval(30 * 1000);

    mGoogleClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    if (mGoogleClient != null)
    {
        mGoogleClient.connect();
    }


}

I'm not sure what else is needed. Please let me know if I need to provide more code.

Edit: Crash log

08-15 17:51:54.692 950-950/? E/AndroidRuntime: FATAL EXCEPTION: main
                                           Process: com.hensh.fusedmap, PID: 950
                                           java.lang.IllegalStateException: GoogleApiClient is not connected yet.
                                               at com.google.android.gms.common.api.internal.zzh.zzb(Unknown Source)
                                               at com.google.android.gms.common.api.internal.zzl.zzb(Unknown Source)
                                               at com.google.android.gms.common.api.internal.zzj.zzb(Unknown Source)
                                               at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
                                               at com.hensh.fusedmap.MapsActivity.onConnected(MapsActivity.java:667)
                                               at com.google.android.gms.common.internal.zzk.zzk(Unknown Source)
                                               at com.google.android.gms.common.api.internal.zzj.zzi(Unknown Source)
                                               at com.google.android.gms.common.api.internal.zzh.zzpx(Unknown Source)
                                               at com.google.android.gms.common.api.internal.zzh.onConnected(Unknown Source)
                                               at com.google.android.gms.common.api.internal.zzl.onConnected(Unknown Source)
                                               at com.google.android.gms.common.api.internal.zzc.onConnected(Unknown Source)
                                               at com.google.android.gms.common.internal.zzj$zzg.zzqL(Unknown Source)
                                               at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source)
                                               at com.google.android.gms.common.internal.zzj$zza.zzw(Unknown Source)
                                               at com.google.android.gms.common.internal.zzj$zzc.zzqN(Unknown Source)
                                               at com.google.android.gms.common.internal.zzj$zzb.handleMessage(Unknown Source)
                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                               at android.os.Looper.loop(Looper.java:135)
                                               at android.app.ActivityThread.main(ActivityThread.java:5294)
                                               at java.lang.reflect.Method.invoke(Native Method)
                                               at java.lang.reflect.Method.invoke(Method.java:372)
                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
fez
  • 511
  • 1
  • 10
  • 27
  • I guess your map is not ready and results in a crash because your code for getting the location is okay. – P-Zenker Aug 15 '16 at 16:14
  • please specify where it crashes. Also why are you calling connect `mGoogleClient.connect();` in your onConnected? – tyczj Aug 15 '16 at 16:15
  • Crash log has been added. the onConnected method is more of a "let's connect now". It crashes when the app opens (but after a while it runs fine) – fez Aug 15 '16 at 16:32
  • @PatrickZenker that's what I want to fix, how can I wait until the map is ready before running any more code – fez Aug 15 '16 at 16:33
  • Your onConnected method is called because, before, somewhere in your code, you called mGoogleClient.connect(). So you should not call again connect() inside onConnected. – fernandospr Aug 15 '16 at 18:33
  • To wait for the map to be ready, you can use MapFragment.getAsync or GoogleMap.setOnMapLoadedCallback – fernandospr Aug 15 '16 at 18:36
  • Unclear exactly where you went wrong, but take a look at this working example for a reference: http://stackoverflow.com/documentation/android/170/google-maps-api-v2-for-android/5557/show-current-location-in-a-google-map#t=201608151922003393625 – Daniel Nugent Aug 15 '16 at 19:23

3 Answers3

2

The GoogleAPIClient needs to be connected before you try to use the service. So your call to connect it in the onConnected is wrong. If you're in onConnected it means the client is connected. You need to build the GoogleAPIClient in the onCreate of your activity and ideally connect it in the onStart of your Activity.

private GoogleApiClient mGoogleApiClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.<your-xml>);

    mGoogleApiClient = new GoogleApiClient.Builder(context)
             .addConnectionCallbacks(this)
             .addOnConnectionFailedListener(this)
             .addApi(LocationServices.API)
             .build();
}
public void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

Additionally, when building the GoogleAPIClient you can also set enableAutoManage() for the connect and disconnect to be managed automatically so that you dont have to do it manually, as explained here.

public class LocationActivity implements GoogleApiClient.OnConnectionFailedListener {

    /** Google Services client */
    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.payment_activity);
        mGoogleApiClient = new GoogleApiClient.Builder(context)
                 .addConnectionCallbacks(this)
                 .enableAutoManage(this, this)
                 .addApi(LocationServices.API)
                 .build();
}
gsb
  • 5,520
  • 8
  • 49
  • 76
0

You should place the code snippet mMap.animateCamera... etc into onMapLoaded.

Detect when Android v2 maps has loaded

And remove mGoogleClient.connect(); in your onConnected method because you don't have to connect twice (or more)

Community
  • 1
  • 1
P-Zenker
  • 385
  • 2
  • 10
0

It's unclear how you want your application to function. If you want your location to be displayed on the map and updated when you move:

  1. Instantiate GoogleApiClient only once in onCreate.
  2. Connect GoogleApiClient in onResume.
  3. In onConnected, make your location request(s)
  4. In onLocationChanged, move your map.

It's probably worthwhile to review: Fatal Exception: java.lang.IllegalStateException GoogleApiClient is not connected yet

Community
  • 1
  • 1
mattm
  • 5,851
  • 11
  • 47
  • 77