FusedLocationProviderApi Fatal exception: GoogleApiClient is not connected yet.

1.6k views Asked by At

I am a newbie android developer. I want to make a some GoogleMaps app which will show some location around user current location. But I haven't captured user location. I looked too many docs, GoogleMap Tutorials from Google. Searched from stackoverflow, but I couldn't find any solution.

There is my HaritaFragment.java

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.parse.FindCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseGeoPoint;
import com.parse.ParseObject;
import com.parse.ParseQuery;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HaritaFragment extends Fragment implements LocationListener, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener  {

    private static GoogleMap mGoogleMap;
    public static HashMap<Marker, Markers> mMarkersHashMap = new HashMap<Marker, Markers>();
    private ArrayList<Markers> mMyMarkersArray = new ArrayList<Markers>();
    private Map<Marker, Markers> allMarkersMap = new HashMap<Marker, Markers>();
    private static List<ParseObject>vetList = new ArrayList<ParseObject>();

    private LatLng latLng;
    private Double lat;
    private Double lng;



    private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
    private static final long INTERVAL = 1000 * 10;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location userLocation;
    String mLastUpdateTime;

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        setHasOptionsMenu(true);

        return inflater.inflate(R.layout.fragment_harita, container, false);
    }

    public void onViewCreated(View view, Bundle savedInstanceState){

    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (isGooglePlayServicesAvailable()) {

            createLocationRequest();
            mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }
    }

        @Override
    public void onStart() {
        super.onStart();
        mGoogleApiClient.connect();

    }

    @Override
    public void onStop() {
        super.onStop();
        //mGoogleApiClient.disconnect();
    }

    @Override
    public void onPause() {
        super.onPause();
        stopLocationUpdates();
    }

    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
    }

    @Override
    public void onResume() {
        super.onResume();

        if (isGooglePlayServicesAvailable()){

            startLocationUpdates();
            setupMap();
            googleAnalyticsSendScreen();
            getAllDataFromParse();
        }
    }

    @Override
    public void onLocationChanged(Location location) {
            /*lat =  (location.getLatitude());
            lng =  (location.getLongitude());*/

        userLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.map_hibrit) {
            mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        }
        else if (id == R.id.map_standart){
            mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        }
        else if (id == R.id.map_uydu){
            mGoogleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConnected(Bundle bundle) {

        startLocationUpdates();
    }

    protected void startLocationUpdates() {
        /*PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);*/

        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

There is the logcat output :

06-11 17:54:43.361  17655-17855/packagename E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.IllegalStateException: GoogleApiClient is not connected yet.
            at com.google.android.gms.internal.fp.a(Unknown Source)
            at com.google.android.gms.common.api.w.a(Unknown Source)
            at com.google.android.gms.internal.hy.a(Unknown Source)
            at packagename.r.P(Unknown Source)
            at packagename.r.t(Unknown Source)
            at android.support.v4.app.Fragment.I(Unknown Source)
            at android.support.v4.app.w.a(Unknown Source)
            at android.support.v4.app.w.a(Unknown Source)
            at android.support.v4.app.e.run(Unknown Source)
            at android.support.v4.app.w.f(Unknown Source)
            at android.support.v4.app.w.b(Unknown Source)
            at android.support.v4.app.ac.b(Unknown Source)
            at android.support.v4.view.ViewPager.a(Unknown Source)
            at android.support.v4.view.ViewPager.c(Unknown Source)
            at android.support.v4.view.ViewPager.onMeasure(Unknown Source)
            at android.view.View.measure(View.java:13011)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4706)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
            at android.view.View.measure(View.java:13011)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4706)
            at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(Unknown Source)
            at android.view.View.measure(View.java:13011)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4706)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
            at android.view.View.measure(View.java:13011)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4706)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
            at android.view.View.measure(View.java:13011)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4706)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2163)
            at android.view.View.measure(View.java:13011)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1084)
            at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2498)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:154)
            at android.app.ActivityThread.main(ActivityThread.java:4944)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
            at dalvik.system.NativeStart.main(Native Method)

What is the problem ? I tried 4.0.1 real HTC devices and 4.4.4 GenyMotion with GooglePlayServices.

I want to get user near locations from Parse.com and I have to capture user location for this method:

if (userLocation != null) {

            ParseGeoPoint parsedLocation = (new ParseGeoPoint(userLocation.getLatitude(), userLocation.getLongitude()));
            ParseQuery<ParseObject> query = ParseQuery.getQuery("Vets");
            query.fromLocalDatastore();
            query.whereNear("location", parsedLocation);
            //query.whereWithinKilometers("location",userLocation,100);
            query.setLimit(250);
            query.findInBackground(new FindCallback<ParseObject>() {
                @Override
                public void done(List<ParseObject> list, ParseException e) {

                    if (e == null) {



                    } else {

                        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                        builder.setTitle(getString(R.string.parse_online_query_error_title));
                        builder.setMessage(getString(R.string.parse_online_query_error_message));
                        builder.setPositiveButton(android.R.string.ok, null);
                        AlertDialog dialog = builder.create();
                        dialog.show();
                    }
                }
            });
        } 

If you show me the another way to do this. It would be good for me. I will not insistence for FusedLocationProviderApi.

Thank you !

1

There are 1 answers

7
James On BEST ANSWER

It looks like you've just got things in the wrong order. It's important to know the order Android takes when starting, pausing and resuming activities.

http://developer.android.com/training/basics/activity-lifecycle/pausing.html

The problem in your code is when you hit onResume the mGoogleApiClient could have not quite connected.

This is the order you should have

  1. Create mGoogleApiClient
  2. Call mGoogleApiClient.connect();
  3. onConnected() gets called automatically.

-- Call startLocationUpdates() from inside onConnected

Doing the above means your Api client is always connected when you request location updates.

I think the quickest way to fix your code is delete your onPause and onResume methods and un-comment the onDisconnect in onStop.

Allow onStart and onStop to handle your connection and the connection in turn to handle the location updates.

Best of luck.