You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

地图显示用户位置失败:GoogleApiClient未连接异常求助

问题分析与修复方案

核心问题拆解

你遇到的java.lang.IllegalStateException: GoogleApiClient is not connected yet异常,本质是异步操作的时机错误:apiClient.connect()是异步执行的,不会立刻完成连接,但你直接在调用connect()后就执行requestLocationUpdates,此时客户端还处于未连接状态。而地图不显示位置,大概率是因为displayLocation的调用时机不对,或者Marker的更新逻辑存在漏洞。

分步修复代码

1. 修正GoogleApiClient连接逻辑,将位置请求移到回调中

首先修改startLocationListener,只负责初始化和触发连接,不要直接请求位置更新:

public void startLocationListener() {
    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || 
        ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(getActivity(), 
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 
            AppConstants.LOC_PERM_CODE);
    } else {
        if (apiClient == null) {
            initAPIClient();
        }
        if (!apiClient.isConnected()) {
            apiClient.connect();
        }
        // 移除这里的requestLocationUpdates,移到onConnected回调中
    }
}

然后在onConnected回调中执行位置请求和初始位置显示(这才是客户端确认连接成功的正确时机):

@Override
public void onConnected(@Nullable Bundle bundle) {
    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        // 开始请求位置更新
        LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this);
        // 获取最后已知位置并显示
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(apiClient);
        if (mLastLocation != null) {
            displayLocation();
        }
    }
}

2. 完善displayLocation方法,确保地图Marker正确更新

确保在拿到位置后,正确创建或更新地图上的Marker,同时移动地图到当前位置:

private void displayLocation() {
    // 先判断地图和位置是否初始化完成
    if (mGmap == null || mLastLocation == null) {
        return;
    }
    
    latitude = mLastLocation.getLatitude();
    longitude = mLastLocation.getLongitude();

    // 更新Marker:如果已有则移除,再创建新的
    if (currentMarker != null) {
        currentMarker.remove();
    }
    LatLng currentLatLng = new LatLng(latitude, longitude);
    MarkerOptions markerOptions = new MarkerOptions()
            .position(currentLatLng)
            .title("Your Current Location")
            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
    currentMarker = mGmap.addMarker(markerOptions);

    // 移动地图到当前位置,缩放级别设为15(适合街景级显示)
    mGmap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15));
}

3. 完善位置更新回调与停止监听逻辑

在onLocationChanged中更新位置并刷新地图:

@Override
public void onLocationChanged(Location location) {
    mLastLocation = location;
    displayLocation(); // 位置变化时实时更新地图显示
}

修正stopLocationListener,确保正确移除更新并断开客户端:

public void stopLocationListener() {
    if (apiClient != null && apiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this);
        apiClient.disconnect();
    }
    if (currentMarker != null) {
        currentMarker.remove();
        currentMarker = null;
    }
}

4. 补充连接异常处理

完善onConnectionSuspended和onConnectionFailed,提升鲁棒性:

@Override
public void onConnectionSuspended(int i) {
    apiClient.connect(); // 连接断开后尝试重新连接
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    Snackbar.make(getActivity().findViewById(android.R.id.content), 
        "GoogleApiClient连接失败: " + connectionResult.getErrorMessage(), 
        Snackbar.LENGTH_LONG).show();
}

5. 修正setUpLocation初始化逻辑

确保权限、Play服务检查后,正确初始化位置请求和客户端:

private void setUpLocation() {
    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || 
        ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(getActivity(), 
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 
            AppConstants.LOC_PERM_CODE);
        return;
    } 
    if (checkPlayServices()) {
        makeLocationRequest();
        initAPIClient();
        if (statusSwitch.isChecked()) {
            apiClient.connect();
        }
    } else {
        Snackbar.make(getActivity().findViewById(android.R.id.content), 
            "你的设备不支持Google Play服务", 
            Snackbar.LENGTH_LONG).show();
    }
}

关键修复要点总结

  1. 永远不要在apiClient.connect()后立刻调用位置相关API,必须等待onConnected回调确认连接成功。
  2. 确保displayLocation只在mGmap和mLastLocation都初始化完成后执行。
  3. 位置变化时,通过onLocationChanged实时更新地图Marker。
  4. 停止监听时,必须移除位置更新并断开GoogleApiClient,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Andromeda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:40:45