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

Android10(API30)下Google Maps API获取当前位置异常求助

解决Android 10(API 30)定位显示谷歌总部的问题

嘿,我来帮你排查这个问题——显示谷歌总部坐标(大概是37.4220° N, 122.0841° W?)通常是定位失败后的默认 fallback 坐标,咱们一步步拆解原因并解决:

1. 最可能的原因:缺失动态权限申请

Android 6.0(API 23)及以上,危险权限(比如位置权限)必须动态申请,哪怕你在Manifest里已经声明了。Android 10(API 30)对位置权限的管控更严格,没有动态授权的话,系统会直接拒绝位置请求,导致FusedLocationProvider返回默认的测试坐标。

解决方案:

在调用getDeviceLocation()之前,先检查并请求位置权限:

// 检查权限是否已授予
private boolean checkLocationPermissions() {
    boolean fineGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
    boolean backgroundGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED;
    return fineGranted && backgroundGranted;
}

// 请求权限
private void requestLocationPermissions() {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION},
            1001); // 自定义请求码
}

// 在Activity的onRequestPermissionsResult里处理授权结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1001) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 权限授予成功,开始获取位置
            getDeviceLocation();
        } else {
            // 权限被拒绝,提示用户开启权限
            Toast.makeText(this, "需要位置权限才能获取当前位置", Toast.LENGTH_SHORT).show();
        }
    }
}

然后在你的Activity初始化时(比如onCreate),先判断权限:

if (checkLocationPermissions()) {
    getDeviceLocation();
} else {
    requestLocationPermissions();
}

2. 定位回调里过早移除更新

你的代码在onLocationResult回调里立刻调用了removeLocationUpdates(this),这会导致:

  • 第一次拿到的可能是缓存的旧位置(比如模拟器默认的谷歌总部坐标)
  • 真实的高精度位置还没来得及返回,就被停止了更新

解决方案:

不要立刻停止更新,而是判断位置是否有效后再停止,或者保留更新一段时间:

@Override
public void onLocationResult(LocationResult locationResult) {
    super.onLocationResult(locationResult);
    if(locationResult != null && locationResult.getLocations().size() > 0) {
        Location latestLocation = locationResult.getLocations().get(locationResult.getLocations().size() -1);
        // 检查位置是否有效:精度小于100米,且是最近1分钟内的位置
        if (latestLocation.getAccuracy() < 100 && System.currentTimeMillis() - latestLocation.getTime() < 60000) {
            double latitude = latestLocation.getLatitude();
            double longitude = latestLocation.getLongitude();
            moveCamera(new LatLng(latitude, longitude), DEFAULT_ZOOM);
            // 拿到有效位置后再停止更新
            LocationServices.getFusedLocationProviderClient(MyMapActivity.this)
                .removeLocationUpdates(this);
        }
    }
}

3. 设备或模拟器设置问题

  • 如果是模拟器测试:默认没有设置真实位置,会返回谷歌总部坐标。你可以在模拟器的「Extended Controls」→「Location」里设置自定义经纬度,或者选择一个真实地点。
  • 如果是真实设备:检查设备的「定位服务」是否开启,并且设置为「高精度模式」(同时使用GPS、Wi-Fi和移动网络)。如果设置为「省电模式」,可能无法获取高精度位置。

4. 额外检查点

  • 确认你的com.google.android.geo.API_KEY是有效的,并且在Google Cloud Console里开启了「Maps SDK for Android」和「Location API」。
  • 检查依赖版本:你的play-services-location版本是17.0.0,建议升级到较新的稳定版(比如21.0.1),避免旧版本的bug。

修改后再测试,应该就能拿到真实的当前位置了!

内容的提问来源于stack exchange,提问作者Majd Kayyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:17:30