1

I'm using flutter_map and geolocator to access an user's location and display it on openstreetmap. The problem is that after some scrolling on the map, this error (Ios simulator: ios 17.5 with iphone 15 pro max and ipad 13inch m4/android simulator pixel 3a/chrome(web)) occurs:

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

This is my code for accessing the user's location and displaying the map:


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
                }
              },
            ),
          ),
        ],
      ),
    );
  }
}

This is what I've tried so far:

adding

    <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" />

to AndroidManifest.xml in android/app/src/main, debug, and profile

adding

    <!-- 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>

in info.plist in ios folder

Ensuring airplane mode is off and wifi is enabled and connected (in simulator)

android internet access picture

apple iphone ipad internet access picture

1 Answer 1

0

not sure if you still looking for answer but the solution/workaround that i use is to change the url used in UrlTemplate from using https to http.

            children: [
              TileLayer(
                urlTemplate: 'http://tile.openstreetmap.org/{z}/{x}/{y}.png',
                userAgentPackageName: 'com.example.app',
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.