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
相关产品推荐
相关产品推荐

