Google Maps无近期位置时无法获取用户定位的问题求助
问题根源
你的代码仅依赖fusedLocationProviderClient.getLastLocation()获取位置,这个方法的局限性很明显:它只返回设备最近缓存的位置数据。如果设备没有近期位置记录(比如刚开机、位置服务刚启用,或长时间未使用定位功能),该方法会直接返回null。而其他应用获取定位时,会触发系统主动更新位置缓存,所以回到你的应用后就能拿到有效数据。
解决方案
要解决这个问题,不能只依赖缓存位置,需要主动请求实时位置更新。核心修改思路如下:
- 配置
LocationRequest,设置定位优先级、更新间隔等参数 - 实现
LocationCallback接收系统返回的实时位置 - 权限通过后,先尝试获取缓存位置,若为
null则启动实时位置更新 - 在页面暂停/销毁时停止位置更新,避免不必要的耗电
修改后的完整代码
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback { private GoogleMap mMap; public static int LOCATION_REQUEST_CODE = 100; FusedLocationProviderClient fusedLocationProviderClient; private LocationRequest locationRequest; private LocationCallback locationCallback; private final LatLng MarisolTerminal = new LatLng(15.1519204,120.4476555); private final LatLng VillaTerminal = new LatLng(15.1268318,120.5974806); private final LatLng CheckpointTerminal = new LatLng(15.169206,120.5872296); private Marker markerMarisolTerm; private Marker markerVillaTerminal; private Marker markerCheckpointTerminal; private Marker userLocationMarker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); if (mapFragment != null) { mapFragment.getMapAsync(this); } fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); initLocationRequestAndCallback(); checkLocationPermission(); } private void initLocationRequestAndCallback() { // 配置定位请求参数 locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(5000); // 5秒更新一次(可按需调整) locationRequest.setFastestInterval(2000); // 最快更新间隔 // 实现位置回调 locationCallback = new LocationCallback() { @Override public void onLocationResult(@NonNull LocationResult locationResult) { super.onLocationResult(locationResult); if (locationResult == null || locationResult.getLocations().isEmpty()) { return; } Location location = locationResult.getLastLocation(); updateUserLocationOnMap(location); // 获取到位置后可停止更新(按需选择) fusedLocationProviderClient.removeLocationUpdates(locationCallback); } }; } @Override public void onMapReady(@NonNull GoogleMap googleMap) { mMap = googleMap; mMap.getUiSettings().setMyLocationButtonEnabled(true); mMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.custom_map_style)); // 添加终端标记 markerMarisolTerm = mMap.addMarker(new MarkerOptions() .position(MarisolTerminal) .title("Marisol Terminal") .icon(BitmapDescriptorFactory.fromResource(R.drawable.marisol))); markerMarisolTerm.setTag(0); markerVillaTerminal = mMap.addMarker(new MarkerOptions() .position(VillaTerminal) .title("Villa Terminal") .icon(BitmapDescriptorFactory.fromResource(R.drawable.villa))); markerVillaTerminal.setTag(0); markerCheckpointTerminal = mMap.addMarker(new MarkerOptions() .position(CheckpointTerminal) .title("Checkpoint Terminal") .icon(BitmapDescriptorFactory.fromResource(R.drawable.checkpoint))); markerCheckpointTerminal.setTag(0); } private void checkLocationPermission() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { getUserLocation(); } else { requestForPermission(); } } private void getUserLocation() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } // 先尝试获取最后缓存的位置 fusedLocationProviderClient.getLastLocation().addOnSuccessListener(location -> { if (location != null) { updateUserLocationOnMap(location); } else { // 没有缓存位置,请求实时位置更新 requestLocationUpdates(); } }); } private void requestLocationUpdates() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); } private void updateUserLocationOnMap(Location location) { LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude()); // 更新用户标记,避免重复添加 if (userLocationMarker != null) { userLocationMarker.setPosition(userLocation); } else { userLocationMarker = mMap.addMarker(new MarkerOptions().position(userLocation).title("I am here")); } // 移动相机到用户位置 mMap.moveCamera(CameraUpdateFactory.newLatLng(userLocation)); mMap.animateCamera(CameraUpdateFactory.zoomTo(15)); } private void requestForPermission() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "Permission Accepted", Toast.LENGTH_SHORT).show(); getUserLocation(); } else { Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show(); } } } @Override protected void onPause() { super.onPause(); // 页面暂停时停止位置更新,节省电量 fusedLocationProviderClient.removeLocationUpdates(locationCallback); } }
关键修改点说明
- 新增
LocationRequest和LocationCallback:主动请求实时位置,解决无缓存位置时的获取问题 - 优化位置获取逻辑:先尝试缓存位置,失败则启动实时更新,获取到位置后可选择停止更新以节省电量
- 用户标记复用:避免重复添加用户位置标记,提升交互体验
- 生命周期管理:在
onPause中停止位置更新,减少不必要的资源消耗
内容的提问来源于stack exchange,提问作者Chichi
相关产品推荐
相关产品推荐

