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

Flutter Web集成Google Maps API加载报错求助

Flutter Google Maps 加载报错排查与修复方案

输入图片描述

我正在尝试在Flutter应用中使用Google Maps API展示附近的药店,已完成所有配置并获取了API Key,也成功申请到了GPS权限,但每当我接受权限后等待应用加载时,都会出现报错信息,尝试过ChatGPT但未能解决问题,相关代码如下:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';


class Pharmacy {
  final String name;
  final String address;
  final double distance;
  final double latitude;
  final double longitude;

  Pharmacy({
    required this.name,
    required this.address,
    required this.distance,
    required this.latitude,
    required this.longitude,
  });
}

class PharmaciesScreen extends StatefulWidget {
  @override
  _PharmaciesScreenState createState() => _PharmaciesScreenState();
}

class _PharmaciesScreenState extends State<PharmaciesScreen> {
  Completer<GoogleMapController> _controller = Completer();
  Set<Marker> _markers = {};

  Position? _currentPosition;

  List<Pharmacy> pharmacies = [
    Pharmacy(name: 'Pharmacy 1', address: '123 Main St', distance: 1.2, latitude: 37.7749, longitude: -122.4194),
    Pharmacy(name: 'Pharmacy 2', address: '456 Maple Ave', distance: 2.5, latitude: 37.7894, longitude: -122.4062),
    Pharmacy(name: 'Pharmacy 3', address: '789 Oak Dr', distance: 3.7, latitude: 37.8030, longitude: -122.4419),
    // Add more pharmacies as needed
  ];

  @override
  void initState() {
    super.initState();
    _getCurrentLocation();
  }

  Future<void> _getCurrentLocation() async {
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    setState(() {
      _currentPosition = position;
    });
  }

  @override
  Widget build(BuildContext context) {
    bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
    Color backgroundColor = isDarkMode ? Colors.grey[850]! : Colors.white;
    Color textColor = isDarkMode ? Colors.white : Colors.black;

    return Scaffold(
      appBar: AppBar(
        title: Text('Pharmacies Near Me', style: TextStyle(color: textColor)),
        backgroundColor: Color(0xFFFC7B32), // Main color of the app
      ),
      body: _currentPosition != null
          ? Stack(
        children: [
          GoogleMap(
            mapType: MapType.normal,
            initialCameraPosition: CameraPosition(
              target: LatLng(_currentPosition!.latitude, _currentPosition!.longitude),
              zoom: 14.0,
            ),
            markers: _markers,
            onMapCreated: (GoogleMapController controller) {
              _controller.complete(controller);
              setState(() {
                _markers.clear();
                for (var pharmacy in pharmacies) {
                  _markers.add(
                    Marker(
                      markerId: MarkerId(pharmacy.name),
                      position: LatLng(pharmacy.latitude, pharmacy.longitude),
                      infoWindow: InfoWindow(
                        title: pharmacy.name,
                        snippet: pharmacy.address,
                      ),
                      onTap: () {
                        // Add logic to open Google Maps with directions to this pharmacy
                      },
                    ),
                  );
                }
              });
            },
          ),
          Positioned(
            bottom: 16.0,
            left: 16.0,
            right: 16.0,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                ElevatedButton(
                  onPressed: () {
                    // Add logic to filter pharmacies by 'Near Me' here
                  },
                  child: Text('Near Me', style: TextStyle(color: textColor)),
                  style: ElevatedButton.styleFrom(
                    primary: Color(0xFFFC7B32), // Main color of the app
                  ),
                ),
                ElevatedButton(
                  onPressed: () {
                    // Add logic to filter pharmacies by '24/7' here
                  },
                  child: Text('24/7', style: TextStyle(color: textColor)),
                  style: ElevatedButton.styleFrom(
                    primary: Color(0xFFFC7B32), // Main color of the app
                  ),
                ),
              ],
            ),
          ),
        ],
      )
          : Center(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

核心问题排查与修复

1. 定位权限与异常处理缺失

原代码直接调用定位接口,未处理权限拒绝、定位服务未开启等异常情况,导致加载失败。修改_getCurrentLocation方法:

Future<void> _getCurrentLocation() async {
  // 检查权限状态
  LocationPermission permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('需要定位权限才能显示附近药店')),
      );
      return;
    }
  }

  // 检查定位服务是否开启
  bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
  if (!isLocationEnabled) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('请先开启设备定位服务')),
    );
    await Geolocator.openLocationSettings();
    return;
  }

  try {
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    setState(() {
      _currentPosition = position;
    });
  } catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('定位失败:${e.toString()}')),
    );
  }
}

2. Google Maps API Key配置验证

  • Android:确保AndroidManifest.xml中正确配置API Key,且放在<application>标签内:
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="你的API密钥"/>
    
  • iOS:在Info.plist中添加配置:
    <key>GoogleMapsAPIKey</key>
    <string>你的API密钥</string>
    
  • 登录Google Cloud控制台,确认API Key已启用Maps SDK for Android和Maps SDK for iOS服务,且应用包名/ Bundle ID与限制规则匹配。

3. 地图标记初始化时序优化

原代码在onMapCreated中才添加标记,导致地图加载初期无标记且可能出现状态不同步问题。提前初始化标记:

@override
void initState() {
  super.initState();
  _initMarkers();
  _getCurrentLocation();
}

void _initMarkers() {
  _markers.clear();
  for (var pharmacy in pharmacies) {
    _markers.add(
      Marker(
        markerId: MarkerId(pharmacy.name),
        position: LatLng(pharmacy.latitude, pharmacy.longitude),
        infoWindow: InfoWindow(
          title: pharmacy.name,
          snippet: pharmacy.address,
        ),
        onTap: () {
          // 导航跳转逻辑示例
          // launchUrl(Uri.parse('https://www.google.com/maps/dir/?api=1&destination=${pharmacy.latitude},${pharmacy.longitude}'));
        },
      ),
    );
  }
}

4. 依赖版本兼容性检查

确保pubspec.yaml中依赖版本与Flutter SDK兼容,推荐使用稳定版本:

dependencies:
  flutter:
    sdk: flutter
  google_maps_flutter: ^2.5.0
  geolocator: ^11.0.0

内容的提问来源于stack exchange,提问作者Nouaman Ahmamcha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:11:24