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

Android Studio中Google Map无法缩放至当前位置问题求助

修复getLastLocation返回null及地图无法缩放至当前位置的问题

问题根源

getLastLocation()仅返回设备上缓存的最后一次位置信息,如果是应用首次启动、设备刚重启或之前位置服务被关闭,缓存位置会不存在,导致返回null,进而无法执行地图缩放逻辑。

修复方案

我们需要添加实时位置请求逻辑,并检查位置服务是否启用,确保能获取到有效位置信息。以下是完整修复后的代码:

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Looper;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;

import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

public class Game_Activity extends FragmentActivity implements OnMapReadyCallback {

    private Location currentLocation;
    private FusedLocationProviderClient fusedClient;
    private static final int REQUEST_CODE = 101;
    private static final int REQUEST_CHECK_SETTINGS = 102;
    private FrameLayout map;
    private GoogleMap mMap;
    private LocationCallback locationCallback;
    private LocationRequest locationRequest;
    private boolean isLocationRequestInProgress = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        map = findViewById(R.id.map);

        fusedClient = LocationServices.getFusedLocationProviderClient(this);
        initializeLocationRequest();
        initializeMap();
        checkLocationSettings();
    }

    private void initializeLocationRequest() {
        // 配置位置请求参数:高优先级、更新间隔
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(5000); // 5秒更新一次
        locationRequest.setFastestInterval(2000); // 最快2秒更新一次

        // 位置回调:获取到实时位置后更新地图
        locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if (locationResult == null) return;
                for (Location location : locationResult.getLocations()) {
                    if (location != null) {
                        currentLocation = location;
                        if (mMap != null) {
                            updateMap();
                        }
                        // 获取到初始位置后停止实时更新
                        if (isLocationRequestInProgress) {
                            fusedClient.removeLocationUpdates(locationCallback);
                            isLocationRequestInProgress = false;
                        }
                    }
                }
            }
        };
    }

    private void initializeMap() {
        // 提前初始化地图,避免等待位置时地图未加载
        SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        if (supportMapFragment != null) {
            supportMapFragment.getMapAsync(this);
        }
    }

    private void checkLocationSettings() {
        // 检查设备位置服务是否启用
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        SettingsClient client = LocationServices.getSettingsClient(this);
        client.checkLocationSettings(builder.build())
                .addOnSuccessListener(locationSettingsResponse -> getLocation())
                .addOnFailureListener(e -> {
                    if (e instanceof ResolvableApiException) {
                        // 位置服务未启用,弹出提示框引导用户开启
                        try {
                            ResolvableApiException resolvable = (ResolvableApiException) e;
                            resolvable.startResolutionForResult(Game_Activity.this, REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException sendEx) {
                            sendEx.printStackTrace();
                        }
                    }
                });
    }

    private void getLocation() {
        if (ActivityCompat.checkSelfPermission(
                this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(
                this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                    REQUEST_CODE);
            return;
        }

        // 先尝试获取缓存位置
        fusedClient.getLastLocation()
                .addOnSuccessListener(location -> {
                    if (location != null) {
                        currentLocation = location;
                        if (mMap != null) {
                            updateMap();
                        }
                    } else {
                        // 无缓存位置时请求实时位置更新
                        if (!isLocationRequestInProgress) {
                            isLocationRequestInProgress = true;
                            fusedClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
                        }
                    }
                })
                .addOnFailureListener(e -> {
                    // 获取缓存位置失败时,直接请求实时更新
                    if (!isLocationRequestInProgress) {
                        isLocationRequestInProgress = true;
                        fusedClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
                    }
                });
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.getUiSettings().setScrollGesturesEnabled(false);
        // 如果位置已提前获取到,直接更新地图
        if (currentLocation != null) {
            updateMap();
        }
    }

    private void updateMap() {
        LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("Player");
        // 直接使用zoom动画,无需先移动再缩放
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
        mMap.addMarker(markerOptions);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getLocation();
            } else {
                Toast.makeText(this, "位置权限未授予,无法获取当前位置", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CHECK_SETTINGS) {
            if (resultCode == RESULT_OK) {
                // 用户开启位置服务后重新获取位置
                getLocation();
            } else {
                Toast.makeText(this, "需要启用位置服务才能使用该功能", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

关键修复点

  1. 添加实时位置请求:当getLastLocation()返回null时,通过LocationRequest和LocationCallback获取实时位置更新
  2. 位置设置检查:通过SettingsClient检查位置服务是否启用,引导用户开启
  3. 提前初始化地图:在启动时就加载地图,避免等待位置时地图未就绪
  4. 统一地图更新逻辑:将地图缩放和标记添加逻辑封装到updateMap()方法,确保位置就绪时能立即更新
  5. 停止不必要的更新:获取到初始位置后停止实时位置更新,节省资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 10:15:56