Flutter使用HuaweiMap时FusedLocationProviderClient获取位置全为null
问题根因
调用FusedLocationProviderClient.getLastLocation()返回全属性为null的Location实例,属于SDK的正常行为,不是代码语法错误,触发原因有三个:
getLastLocation()本身不会主动发起定位请求,只会读取设备本地缓存的历史定位结果。如果设备此前没有任何应用触发过定位、系统清理了定位缓存、用户开关过一次定位开关清空了缓存,这个接口就会直接返回全空的Location对象,不会抛出异常。- 你的代码中虽然创建了
LocationRequest并配置了定位间隔,但从未调用requestLocationUpdates()发起主动定位流程,设备不会生成新的定位结果写入缓存,自然读不到有效数据。 - 构造
LocationSettingsRequest时你传入了一个全新的空LocationRequest()实例,之前配置了interval参数的locationRequest实例根本没有被用到,参数配置完全不生效。
修复方案
按以下步骤修改代码即可:
- 补全权限逻辑:仅校验权限状态不够,权限未授予时要主动发起权限申请,不要直接返回null。
- 修正配置传递:构造
LocationSettingsRequest时传入你提前配置好参数的locationRequest实例,不要新建空对象。 - 替换定位获取逻辑:不要单独依赖
getLastLocation()读缓存,改用requestLocationUpdates()主动发起定位请求,如果只需要单次获取位置,配置numUpdates = 1即可,拿到第一个有效结果后SDK会自动停止定位。 - 给
LocationRequest补充优先级配置,设置为高精度模式,提升定位成功率。
参考修正代码:
var permissionHandler = PermissionHandler(); var permissionStatus = await permissionHandler.hasLocationPermission(); if (!permissionStatus) { permissionStatus = await permissionHandler.requestLocationPermission(); if (!permissionStatus) return null; } var locationService = FusedLocationProviderClient(); // 统一配置定位参数 var locationRequest = LocationRequest(); locationRequest.interval = 5000; locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY; locationRequest.numUpdates = 1; // 单次定位场景配置,拿到1次结果后自动停止 var locationSettingsRequest = LocationSettingsRequest( requests: [locationRequest], // 传入配置好的实例,不要新建空对象 alwaysShow: true, needBle: false, ); try { var settingState = await locationService.checkLocationSettings(locationSettingsRequest); if (!settingState.locationPresent) { // 定位开关/设置不满足要求时,可在此处引导用户开启定位 return null; } // 主动发起定位请求监听结果 locationService.requestLocationUpdates(locationRequest).listen((validLocation) { if (validLocation.latitude != null && validLocation.longitude != null) { print("获取到有效定位:$validLocation"); // 如果是持续定位场景不需要这行,单次场景可以手动移除监听做兜底 locationService.removeLocationUpdates(locationRequest); } }); // 可选优化:如果本地已有有效缓存可以直接用,减少等待时间 // final cacheLocation = await locationService.getLastLocation(); // if (cacheLocation.latitude != null && cacheLocation.longitude != null) { // print("使用缓存定位结果:$cacheLocation"); // } } catch (e) { print("定位流程出错:$e"); }
排查注意事项
- 确认项目
AndroidManifest.xml中已经配置华为定位所需的全部权限:基础定位需要ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION,Android 12及以上版本需要后台定位的话还要补充ACCESS_BACKGROUND_LOCATION。 - 测试阶段尽量使用真机,模拟器定位能力经常存在异常;室内测试时建议打开WLAN、移动网络辅助定位,提升定位速度和成功率。
- 确认已经在华为AppGallery Connect对应项目下开通了定位服务权限,并且最新的
agconnect-services.json配置文件已经放到项目android/app目录下。
内容的提问来源于stack exchange,提问作者Dawid Długosz
相关产品推荐
相关产品推荐

