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
相关产品推荐
相关产品推荐

