Flutter – Geolocator package is not calling Geolocator.getCurrentPosition() more than once

Issue

As the title says, I’m not being able to call Geolocator.getCurrentPosition() more than once. I have logged the issue with the package team, but I’m wondering if it’s something I’m doing wrong.

  Future getLocation() async {
    var currentLocation;
    try {
      currentLocation = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.medium,
      );
    } catch (e) {
      currentLocation = null;
    }
    return currentLocation;
  }

  void getLocation1() async {
    var location = await getLocation();
    print(location);
    print("First");
  }

  void getLocation2() async {
    var location = await getLocation();
    print(location);
    print("Second");
  }

  @override
  void initState() {
    super.initState();
    getLocation1();
    getLocation2();
  }

The console prints "Second" but not "First". When I remove the getLocation2() call, the console prints "First". They are not able to be called in the same frame, and I don’t know why this changed. Am I doing anything wrong?

Solution

I am assuming you are experiencing this behavior on iOS or macOS. The reason is that Apple doesn’t allow multiple active calls to the location stream. What happens is that the getLocation2 method closes the active request currently running by the getLocation1 call.

The easiest way to workaround this, is to return the same Future if the first request has not been finished yet:

  late Future<Position> _positionFuture;

  Future<Position> getLocation() async {
    if (_positionFuture != null && !_positionFuture!.isCompleted) {
      return _positionFuture;
    }

    _positionFuture = Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.medium,
      );
    return _positionFuture;
  }

  void getLocation1() async {
    var location = await getLocation();
    print(location);
    print("First");
  }

  void getLocation2() async {
    var location = await getLocation();
    print(location);
    print("Second");
  }

  @override
  void initState() {
    super.initState();
    getLocation1();
    getLocation2();
  }

Answered By – Maurits van Beusekom

Answer Checked By – Marie Seifert (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *