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