FusedLocationProviderApi 致命异常:GoogleApiClient 尚未连接。

FusedLocationProviderApi Fatal exception: GoogleApiClient is not connected yet.

我是新手 android 开发人员。我想制作一些 Google 地图应用程序,它将显示用户当前位置周围的一些位置。但我还没有捕获用户位置。我看了太多文档,Google来自 Google 的地图教程。从 Whosebug 搜索,但我找不到任何解决方案。

有我的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) {

    }

有 logcat 输出:

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)

问题是什么?我用 GooglePlayServices.

尝试了 4.0.1 真正的 HTC 设备和 4.4.4 GenyMotion

我想让用户靠近 Parse.com 的位置,我必须为此方法捕获用户位置:

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

如果你告诉我另一种方法来做到这一点。这对我有好处。我不会坚持 FusedLocationProviderApi.

谢谢!

看起来你刚刚弄错了顺序。了解开始、暂停和恢复活动时的顺序 Android 很重要。

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

您的代码中的问题是当您点击 onResumemGoogleApiClient 可能没有完全连接。

这是你应该有的顺序

  1. 创建 mGoogleApi客户端
  2. 调用mGoogleApiClient.connect();
  3. onConnected() 被自动调用。

-- 从 onConnected

内部调用 startLocationUpdates()

执行上述操作意味着您的 Api 客户端在您请求位置更新时始终处于连接状态。

我认为修复代码的最快方法是删除 onPauseonResume 方法并取消注释 onStop 中的 onDisconnect。

允许 onStartonStop 处理您的连接,然后该连接依次处理位置更新。

祝你好运。