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

Flutter_map加载OpenStreetMap瓦片出现SocketException问题求助

问题描述

使用flutter_map和geolocator获取用户位置并在OpenStreetMap上展示,在iOS模拟器(iOS 17.5,iPhone 15 Pro Max、iPad 13英寸M4)、Android模拟器(Pixel 3a)及Chrome网页端,滚动地图一段时间后出现错误:

flutter: ClientException with SocketException: Failed host lookup: 'tile.openstreetmap.org' (OS Error: nodename nor servname provided, or not known, errno = 8), uri=https://tile.openstreetmap.org/.....png

定位及地图展示代码

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:project/components/compass/compass.dart';
import 'package:project/components/user_location.dart';
import 'dart:async';

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  LatLng? _currentPosition;
  late final MapController _mapController;
  bool _isMapInitialized = false;
  bool _isCenteredOnUser = true;
  StreamSubscription<Position>? _positionStreamSubscription;

  @override
  void initState() {
    super.initState();
    _mapController = MapController();
    _requestPermission();
  }

  void _requestPermission() async {
    final status = await Permission.location.request();
    if (status.isGranted) {
      print('Location Permission granted');
      if (_isMapInitialized && mounted) {
        _getCurrentLocation();
        _startLocationUpdates();
      }
    } else if (status.isDenied) {
      print('Location Permission denied');
    } else if (status.isPermanentlyDenied) {
      print('Location Permission permanently denied');
    }
  }

  void _getCurrentLocation() async {
    try {
      Position position = await Geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.high);
      if (mounted) {
        setState(() {
          _currentPosition = LatLng(position.latitude, position.longitude);
          _mapController.move(_currentPosition!, 14);
        });
      }
    } catch (e) {
      if (mounted) {
        print("Error getting location: $e");
      }
    }
  }

  void _startLocationUpdates() {
    const locationSettings = LocationSettings(
      accuracy: LocationAccuracy.high,
      distanceFilter: 10, // minimum distance to trigger update
    );

    _positionStreamSubscription =
        Geolocator.getPositionStream(locationSettings: locationSettings).listen(
      (Position position) {
        if (mounted) {
          setState(() {
            _currentPosition = LatLng(position.latitude, position.longitude);
            if (_isCenteredOnUser) {
              _mapController.move(_currentPosition!,
                  16); // Keep the map centered if the icon is blue
            } else {
              // Map has been moved by the user, update the icon color
              setState(() {
                _isCenteredOnUser = false;
              });
            }
          });
        }
      },
      onError: (e) {
        if (mounted) {
          print("Error in location stream: $e");
        }
      },
    );
  }

  @override
  void dispose() {
    _positionStreamSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          FlutterMap(
            mapController: _mapController,
            options: MapOptions(
              interactionOptions: const InteractionOptions(
                enableMultiFingerGestureRace: true,
                flags: InteractiveFlag.doubleTapDragZoom |
                    InteractiveFlag.doubleTapZoom |
                    InteractiveFlag.drag |
                    InteractiveFlag.flingAnimation |
                    InteractiveFlag.pinchZoom |
                    InteractiveFlag.scrollWheelZoom |
                    InteractiveFlag.rotate,
              ),
              initialZoom: 8,
              onMapReady: () {
                if (mounted) {
                  setState(() {
                    _isMapInitialized = true;
                  });
                  _getCurrentLocation();
                  _startLocationUpdates();
                }
              },
              onPositionChanged: (MapCamera position, bool hasGesture) {
                if (hasGesture) {
                  setState(() {
                    _isCenteredOnUser = false;
                });
                }
              },
            ),
            children: [
              TileLayer(
                urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                userAgentPackageName: 'com.example.app',
              ),
              const MapCompass.cupertino(
                hideIfRotatedNorth: false,
              ),
              if (_currentPosition != null)
                MarkerLayer(
                  markers: [
                    Marker(
                      width: 24,
                      height: 24,
                      point: _currentPosition!,
                      child: const CustomLocationMarker(),
                    ),
                  ],
                ),
              const RichAttributionWidget(
                attributions: [
                  TextSourceAttribution(
                    'OpenStreetMap contributors',
                  )
                ],
              ),
            ],
          ),
          Positioned(
            bottom: 92,
            right: 32,
            child: IconButton(
              icon: Icon(
                Icons.my_location_outlined, 
                color: _isCenteredOnUser ? Colors.blue : Colors.grey,
                size: 64, 
              ),
              onPressed: () {
                if (_currentPosition != null) {
                  setState(() {
                    _isCenteredOnUser = true;
                  });
                  _mapController.move(
                      _currentPosition!, 16); // Zoom level 16 for closer view
                }
              },
            ),
          ),
        ],
      ),
    );
  }
}

已尝试的解决操作

  • 在AndroidManifest.xml的main、debug、profile目录下添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • 在iOS的info.plist中添加配置:
<!-- Permission while running on backgroud -->
<key>UIBackgroundModes</key>
<string>location</string>
<!-- Permission options for the `location` group -->
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location.</string>
  • 确保模拟器关闭飞行模式且Wi-Fi已连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:29:51