Flutter使用location库实现Google Maps定位报currentLatLng未初始化错误
问题原因
- 核心时序问题:你使用
late修饰currentLatLng,但该变量的赋值在异步定位方法get()中执行。initState触发异步定位后不会等待结果返回,会立刻执行build方法,此时定位请求尚未完成,currentLatLng未初始化就被传入CameraPosition,直接触发LateInitializationError。 - 权限缺失问题:
location库需要主动申请定位权限才可以获取位置信息,未申请权限时getLocation()会执行失败,currentLatLng永远不会被赋值。iOS系统对定位权限管控更严格,因此无论调试还是发布模式都会崩溃;Android调试模式可能是此前已经授予过定位权限,刚好赶在build前完成了定位赋值,才出现调试正常的巧合现象。 - 混淆配置问题:Android发布模式如果没有添加
location库的混淆规则,也可能导致定位相关类被误裁剪,引发定位失败崩溃。
解决方案
步骤1:调整变量定义,规避late未初始化风险
将currentLatLng改为可空类型,或设置默认初始定位值,避免未初始化就被访问:
// 方式1:改为可空类型 LatLng? currentLatLng; // 方式2:设置默认初始值(二选一即可) // LatLng currentLatLng = const LatLng(39.9042, 116.4074);
步骤2:补充权限申请与异常捕获逻辑
在获取定位前先检查、申请定位权限,同时添加异常捕获避免定位失败引发崩溃:
get() async { // 先检查定位服务是否开启 bool serviceEnabled = await location.serviceEnabled(); if (!serviceEnabled) { serviceEnabled = await location.requestService(); if (!serviceEnabled) return; } // 检查定位权限 PermissionStatus permissionGranted = await location.hasPermission(); if (permissionGranted == PermissionStatus.denied) { permissionGranted = await location.requestPermission(); if (permissionGranted != PermissionStatus.granted) return; } // 加异常捕获 try { _locationData = await location.getLocation(); latitude = _locationData.latitude; longitude = _locationData.longitude; setState(() { currentLatLng = LatLng(latitude, longitude); }); } catch (e) { print("定位失败:$e"); } }
步骤3:build方法添加加载状态判断
定位完成前先显示加载占位,不要直接渲染GoogleMap:
@override Widget build(BuildContext context) { return Scaffold( body: currentLatLng == null ? const Center(child: CircularProgressIndicator()) : GoogleMap( myLocationEnabled: true, onCameraMove: (CameraPosition cameraPosition) { print(cameraPosition.zoom); }, initialCameraPosition: CameraPosition(target: currentLatLng!, zoom: 15.0), ), ); }
步骤4:补充Android发布模式配置
在android/app/proguard-rules.pro中添加location库的混淆规则:
-keep class com.lyokone.location.** { *; }
同时确认android/app/src/main/AndroidManifest.xml中已经添加定位权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
步骤5:补充iOS权限配置
在ios/Runner/Info.plist中添加定位权限说明:
<key>NSLocationWhenInUseUsageDescription</key> <string>需要定位权限以展示当前位置</string> <key>NSLocationAlwaysUsageDescription</key> <string>需要定位权限以展示当前位置</string>
内容的提问来源于stack exchange,提问作者Mohammed Nabil
相关产品推荐
相关产品推荐

