google_maps_flutter自定义Marker图标报错:无权限启用MyLocation图层
问题根因
你遇到的Cannot enable MyLocation layer as location permissions are not granted报错属于典型的连锁触发的假异常,和自定义图标的分类匹配逻辑本身没有直接冲突,本质是两处代码缺陷叠加打断了地图SDK的正常初始化流程:
- 图标异步加载和地图渲染的竞态冲突:
BitmapDescriptor.fromAssetImage是异步方法,你在initState里立刻启动图标加载,不等返回结果就直接构建Marker、初始化地图,此时从bitmapsHashMap里取到的大多是null值,传给Marker的icon参数后直接触发地图底层渲染崩溃,打断了后续的权限申请检测流程,让SDK抛出权限未授予的误导性报错。 - 资源加载流程的容错缺失:没有在
pubspec.yaml中声明自定义图标的资源路径,部分图标加载失败直接抛出异常,进一步放大了渲染崩溃的影响。
这也是为什么你把自定义图标相关代码注释掉之后,应用就能正常运行——整个崩溃触发链路被切断了,SDK能正常走完权限申请流程。
具体修复步骤
- 调整初始化流程的先后顺序
把原来“边加载图标、边画Marker、边初始化地图”的并行逻辑,改成串行依赖流程:等所有自定义图标全部加载完成、所有点位数据全部拉取结束之后,再构建Marker集合、初始化地图组件,从根源避免异步竞态导致的null传参问题。核心调整逻辑参考:
在地图组件的构建逻辑里,只有等// 用状态标识所有资源是否准备完成 bool _assetsReady = false; Set<Marker> _markers = {}; late final Map<String, BitmapDescriptor> _iconMap; @override void initState() { super.initState(); _prepareAllResources(); } Future<void> _prepareAllResources() async { // 第一步:逐类加载所有自定义图标,全部加载完成再往下执行 _iconMap = {}; for (String category in categories) { final icon = await BitmapDescriptor.fromAssetImage( const ImageConfiguration(size: Size(48, 48)), 'lib/assets/categorie_icons_location/$category.png' ); _iconMap[category] = icon; } // 第二步:拉取点位数据,构建Marker集合,给icon加兜底值 _markers = docs.map<Marker>((doc) { return Marker( markerId: MarkerId('_${doc['title']}_${doc['latitude']}_${doc['longitude']}'), position: LatLng(double.parse(doc['latitude']), double.parse(doc['longitude'])), // 拿不到对应分类的图标时,兜底用系统默认标记,杜绝null传参 icon: _iconMap[doc['category']] ?? BitmapDescriptor.defaultMarker, infoWindow: InfoWindow( title: doc['title'], snippet: doc['street'], ), ); }).toSet(); // 第三步:所有资源准备完成后,更新UI加载地图 setState(() { _assetsReady = true; }); }_assetsReady为true时,才传入构建好的_markers集合,避免空标记触发渲染异常。 - 补全资源路径声明
打开pubspec.yaml,在flutter节点下显式声明自定义图标的存储目录,避免异步加载时因找不到资源抛出异常:flutter: assets: - lib/assets/categorie_icons_location/ - 补全运行时权限适配
仅在AndroidManifest.xml中声明定位权限是不够的,Android 6.0以上的定位权限属于危险权限,必须通过权限插件动态向用户申请授权,等用户授予定位权限之后,再开启地图的myLocationEnabled开关,不要在权限未获取时直接强制开启我的位置图层。 - 版本兼容说明
你当前使用的google_maps_flutter: ^1.0.6是早期大版本,本身存在大量和异步图标加载相关的已知bug,如果完成上述调整后仍有异常,可以升级到当前稳定的3.x版本,SDK已经针对图标加载的异常场景做了大量容错处理。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

