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

FusedLocationProvider首次定位成功 关闭GPS后再次定位失败问题咨询

问题原因及修复方案

核心原因

  • 定位设置检查逻辑仅处理了失败回调,未处理成功回调:当关闭GPS后再次点击定位,代码进入定位设置校验分支,若此时定位设置符合要求,因为没有成功回调触发后续定位逻辑,会直接卡住无响应。
  • 定位回调未及时移除:requestLocationUpdates注册的miUbicacionCallback在拿到定位结果后没有主动移除,FusedLocationProvider会持续持有该回调,多次触发定位时会出现资源冲突,导致新的定位请求不生效。
  • getLastLocation缓存机制限制:该方法返回的是系统缓存的历史定位结果,即使GPS关闭后缓存也不会清空,再次开启GPS定位时可能直接返回过期缓存,不会触发新的实时定位请求,看起来像定位未生效。
  • 代码存在语法错误:locationManager初始化语法错误、定位服务常量大小写错误、点击事件未正确调用permiso()方法,也可能导致偶发的定位失败。

修复步骤

1. 补全定位设置检查的成功回调

在checkLocationSettings调用处添加成功回调,定位设置满足要求时直接触发定位:

Task<LocationSettingsResponse> tarea = LocationServices.getSettingsClient(requireContext()).checkLocationSettings(builder.build());
// 新增成功回调
tarea.addOnSuccessListener(locationSettingsResponse -> {
    obtenerUbicacion();
});
tarea.addOnFailureListener(e -> {
    // 保留原有失败处理逻辑
    if (e instanceof ResolvableApiException) {
        try {
            IntentSenderRequest intentSenderRequest = new IntentSenderRequest.Builder(((ResolvableApiException) e).getResolution()).build();
            contratoGps.launch(intentSenderRequest);
        } catch (Throwable trowable) {
            Log.e("gps", trowable.getMessage());
        }
    }
});

2. 拿到定位结果后及时移除回调

修改定位回调,收到结果后立刻停止定位更新,避免资源占用:

private LocationCallback miUbicacionCallback = new LocationCallback() {
    @Override
    public void onLocationResult(@NonNull LocationResult resultado) {
        if (resultado == null || resultado.getLastLocation() == null) {
            return;
        }
        Location location = resultado.getLastLocation();
        Log.d("UBICACION", location.getLatitude() + " " + location.getLongitude());
        // 新增:移除定位回调,停止接收更新
        proveedor.removeLocationUpdates(this);
    }
};

3. 修复语法错误

// 修正locationManager初始化
locationManager = (LocationManager) requireActivity().getSystemService(Context.LOCATION_SERVICE);
// 修正点击事件调用
tvLocalizar.setOnClickListener(v -> permiso());

4. (可选)优化单次定位逻辑

如果需要获取实时的单次定位,建议用getCurrentLocation替代getLastLocation,无需自行处理缓存为空的逻辑,可靠性更高:

// 替换原有proveedor.getLastLocation()的调用
proveedor.getCurrentLocation(locationRequest.getPriority(), null)
    .addOnSuccessListener(location -> {
        if (location != null) {
            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
            Log.d("UBICACION", location.getLatitude() + "" + location.getLongitude());
        }
    }).addOnFailureListener(e -> {
        Toast.makeText(requireContext(), "error" + e.getMessage(), Toast.LENGTH_SHORT).show();
    });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 01:27:02