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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:46:22