You need to enable JavaScript to run this app. google_maps_flutter自定义Marker图标报错:无权限启用MyLocation图层
优惠活动
大模型
产品
解决方案
定价
更多

google_maps_flutter自定义Marker图标报错:无权限启用MyLocation图层

问题根因

你遇到的Cannot enable MyLocation layer as location permissions are not granted报错属于典型的连锁触发的假异常,和自定义图标的分类匹配逻辑本身没有直接冲突,本质是两处代码缺陷叠加打断了地图SDK的正常初始化流程:

  • 图标异步加载和地图渲染的竞态冲突:BitmapDescriptor.fromAssetImage是异步方法,你在initState里立刻启动图标加载,不等返回结果就直接构建Marker、初始化地图,此时从bitmaps HashMap里取到的大多是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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 23:06:07