Flutter-geolocator: Future never resolves on IOS13

Created on 29 Apr 2020  Β·  63Comments  Β·  Source: Baseflow/flutter-geolocator

πŸ› Bug Report

When I try to getCurrentLocation, it never resolves. I'm not expert on IOS, so please if I forgot to do something, just explain it to me.

Future<Position> getCurrentPosition({
    LocationAccuracy accuracy = LocationAccuracy.best,
    GeolocationPermission geolocationPermission =
        GeolocationPermission.location,
  }) =>
      _geolocator.getCurrentPosition(
        desiredAccuracy: accuracy,
        locationPermissionLevel: geolocationPermission,
      );

Podfile:

config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
         'PERMISSION_LOCATION=1',
      ]

Info.plist:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Need location when in use</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Always and when in use!</string>
    <key>NSLocationUsageDescription</key>
    <string>Older devices need location.</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Can I haz location always?</string>

EDIT:

I've tested on a real Android device and the problem is happening too.

My manifest location permissions:

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

Expected behavior

Return a Position.

Reproduction steps

Just call geolocator.GetCurrentPosition.

Version: 5.1.5.

Platform:

  • [x] :iphone: iOS (Tested with IOS Simulator)
  • [x] :robot: Android (Tested on a Xiomi Pocophone F1 with Android 10QkQ1.190828.002)
android ios triage

Most helpful comment

Hi everybody,

I am happy to announce the I (finally) released version 6.0.0-rc.1 which should get rid of all these problems.

I would really appreciate if you could give it a try and give me your feedback.

All 63 comments

I'm getting the same error. This is happening both on iOS and Android.....

I'm getting the same error on simulator running iOS 10.3 or iOS 13.4 and also on my iPad with iOS 13.4.

mycode.dart:

Position pos = await Geolocator()
              .getCurrentPosition(
                  locationPermissionLevel:
                      GeolocationPermission.locationWhenInUse,
                  desiredAccuracy: LocationAccuracy.high)

Info.plist:

<key>NSLocationAlwaysUsageDescription</key>
<string>Can I haz location always?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Need location when in use</string>

Version: 5.3.1

Same problem for me on Android 8.0. I consider writing a 10-sec timer directly on the source code that throws if reached.

@brenoasm are you experiencing this issue on the simulator or a real device?

@dammel On the simulator it is important to configure the simulator to emit a location. This can be done using the following menu items of the simulator application: Features -> Location -> (select a option other then "none").

@mvanbeusekom What if a real device doesn't emit a location? It shouldn't if the user had turned off GPS, should it?

@mvanbeusekom I've tested on the Simulator for IOS (I don't have an IPhone to test it on a real device). I've tested it on a real Android device and got the same problem... I'll edit and add my Android device information.

I have the same issue with real android device...

@mvanbeusekom Thanks for your help. Your Tipp for the simulators worked for me.
I havenΒ΄t changed anything, but it is now working on the iPad (real device) again.

Tested on an iOS simulator and an iOS device, I had no problem but I have the same problem on an Android emulator

I will try to explain my case in detail.

First, the issue happens in both Android and iPhone devices (I'm using Testflight to test the app with my QA team), but also in Android Emulator and iOS Simulator.

The method 'getCurrentPosition' sometimes doesn't return a position, but after a succession of tries it does. I usually have this problem when I install the app for the first time. After a period of time, suddenly the method start to bring you the current position.

The problem of this issue is that it doesn't happens always. You can install the app, and sometimes in the first try the method return the current position...

Extra notes:

  1. If the method start to work well and I do a hot reload or a hot restart, the method continues to work well
  2. The method doesn't throw any exception... but if you put an 'await' it stops indefinitely
  3. I tried to use an older version of Geolocator, and the problem persist
  4. I'm using Google Maps in my project, so I thought "maybe there is a conflict with a recent version of Maps... ?". Nope. I compile with old versions of Google Maps and the problem persist
  5. The curious thing is that some weeks ago I didn't experience this issue...

My environment:

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[βœ“] Flutter (Channel stable, v1.12.13+hotfix.9, on Linux, locale en_GB.UTF-8)

[βœ“] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[βœ“] Android Studio (version 3.6)
[βœ“] IntelliJ IDEA Community Edition (version 2019.3)
[βœ“] Connected device (2 available)

β€’ No issues found!

Temporary solution in my project:

  1. I added a timeout to the 'getCurrentPosition' method, and if it returns 'null' I start a timer and try again and again... after a little while (sometimes seconds, sometimes even a minute) the method returns the current position
  2. If I need an initial position, I use the method 'getLastKnownPosition()'

I guess #375 and #386 are related to this issue

Same problem here, LG G6, Android 9.0.

Never resolves.

There is an odd way how I can get it to work:
I start google maps app to get the position there. For that I need to activate the positionsensor and wifi (probably mobil dataconnection would also work, not tested).
So I get the position in google maps.
After that it also works in my app (no matter whether the my app was startet afterwards or already running).
If I terminate wifi or switch off the position then it doesn't work anymore, even if I switch them on again.

Closing google maps at any time, even before my app is opened, doesn't matter (but sometimes I have to open google maps more than once.)
It seems to me like google maps establishes something that persists even after maps is closed and that is needed by geolocator.

Edit/Correction:
It's even more complicated, the procedure with google maps worked with all arguments for "desiredAccuracy", but when switching of the wifi there were 2 categories:

  • LocationAccuracy.best and LocationAccuracy.high were still working but became slower
  • LocationAccuracy.medium, LocationAccuracy.lower and LocationAccuracy.lowest didn't resolve anymore, also with those arguments the locationsymbol in the statusbar is never shown.

After rebooting the device location doesn't resolve anymore. So I need to repeat getting location with google maps and then it works again as described.

(Something probably unimportant, unrelated, after a new installation of the app the permission dialog looks different, doesn't have the "Don't ask again"-checkbox, but only the first time the dialog is shown, after that it's always the same dialog with the checkbox)

Same issue, Android 10, OnePlus 7 Pro.

The above described trick with google maps didn't work for me, but somehow after some time the location started resolving without me doing anything specific. i was just reading a previously opened page in the browser, then switched back to my app and saw a a dialog that told me the location - the dialog is set up to show when the future resolves, so eventually it did resolve, but it took awhile. After that the location was resolving fine on every attempt.
As mentioned above after reboot the location doesn't resolve anymore.

On the simulator everything works just fine.

After the message of @SchmadenSchmuki, I made some tests in my project, and this is my conclusion: There is something wrong with the Google Maps Plugin that affects Geolocator plugin. There is an incompatibility between them.

This is the flow of my app when I start it for the first time:

  1. It shows a splash screen
  2. Meanwhile, the app connect to an API to pull user data
  3. I use Geolocator to locate the current position of the user
  4. The app quits the splash screen, and then I show a map showing where the user is located

With this flow, the app fails. The 'getCurrentPosition()' method of Geolocator fails, it never returns a value. NOTE: the methods 'isLocationServiceEnabled()' and 'getLastKnownPosition()' works fine.

BUT if I change the flow to:

  1. The splash screen
  2. Connect to the API to pull user data
  3. Renderize the map with a random location
  4. Use Geolocator to locate the current position of the user
  5. Move the camera of the map to the current position

IT WORKS!!!!!

So, my conclusion is that, in some way, the Google Maps plugin occupy "something" that blocks others plugins to use the geolocation service. When the Google Maps renderizes, it frees that "something" and then everyone can work without problem.

If someone else can confirm that, we can open an issue to Flutter guys to see this

@KnucklesEQ thank you very much for the extensive reporting. I will start debugging this issue and spend more of my time reproducing and hopefully fixing the issue. It would be very helpful if others here could verify if they are all also using the Google Maps plugin?

Never the less I think there are multiple issues (differences between Android 9 + Android 10, iOS sometimes takes many seconds to return a location, using Geolocator in combination with Google Maps) and I will start focusing on all of those and see if I can improve the situation. This will take some time though so please bear with me while I do my best and will try to leave updates here on my progress.

I'm not using Maps plugin. I've noticed that when I grant permission only while the app is running (locationWhenInUse), the next time I ask it will not show and never resolves (Android only, on IOS It never worked since I opened this issue).

I'm not using Google Maps plugin.

Not using Google Maps plugin either.
(When having problems I checked if the google maps app also has problems to get the location and then I saw that getting the location there had an effect on my app)

more details:
the issue occurs when the following conditions are true

  • i'm using location manager (Geolocator().forceAndroidLocationManager = true)
  • i'm using default location accuracy, which is LocationAccuracy.best
  • i am inside

i traced it through the code and what happens is that under the first 2 conditions the location provider that gets picked is 'gps' and the device just can't pick up the gps signal inside. I stepped out to the balcony and almost immediately things started working normally.

I didn't try playing with location accuracy to see how it affects location provider choice, but i did try just forcing the provider to 'network' (by hardcoding). That works, but the accuracy on the retrieved location obviously wasn't very good - ~1080 meters.

@minusminuszero is right, it's the same for me.
So for me it's doing what it should, also immediately after reboot, sorry for the inconveniences.
(I don't set the location manager, so it's forceAndroidLocationManager = false in my case. I use LocationAccuracy.best and guess it would also work with LocationAccuracy.high, probably doesn't work for a lower accuracies because in these cases the locationsymbol doesn't show up in the status bar, but there is already an issue for that.)

I am experiencing the above as well, with the exact same steps to reproduce (being inside, default location acc, etc)

more details:
the issue occurs when the following conditions are true

  • i'm using location manager (Geolocator().forceAndroidLocationManager = true)
  • i'm using default location accuracy, which is LocationAccuracy.best
  • i am inside

i traced it through the code and what happens is that under the first 2 conditions the location provider that gets picked is 'gps' and the device just can't pick up the gps signal inside. I stepped out to the balcony and almost immediately things started working normally.

I didn't try playing with location accuracy to see how it affects location provider choice, but i did try just forcing the provider to 'network' (by hardcoding). That works, but the accuracy on the retrieved location obviously wasn't very good - ~1080 meters.

How did you go about forcing the "network" location? This would be sufficient for me in terms of fixing the issue as it happens indoors at least

How did you go about forcing the "network" location? This would be sufficient for me in terms of fixing the issue as it happens indoors at least

I did so by hardcoding the value for location provider directly in geolocator plugin code. I suppose choosing the low accuracy would have the same effect, but i didn't try.

Probably the method should have a timeout param, no?

Is the Flutter/Geolocator team working on this issue?

Yes we are

Thank you @mvanbeusekom!
Do you know what is the source of the problem?
Have you found a way to bypass it (or some kind of temporary solution)?
(downgrading to 4.0.3 did not solve it for us)

On the simulator it is important to configure the simulator to emit a location. This can be done using the following menu items of the simulator application: Features -> Location -> (select a option other then "none").

That fixed the issue for me. But it's a very confusing bug as it just fails without any exceptions or anything.

On the simulator it is important to configure the simulator to emit a location. This can be done using the following menu items of the simulator application: Features -> Location -> (select a option other then "none").

That fixed the issue for me. But it's a very confusing bug as it just fails without any exceptions or anything.

Yup, for me too.
Please add timeout in location request and throw an exception in simulator that has no location set.

Thanks :)

I have the same problem on iOS, I'm also using the google maps plugin.
I have an app that uses getLocationStream but I don't get a permission dialog until I go on the tab where I have a google map.
I have another app where I didn't use google maps anymore but forgot to remove the plugin and I had the same problem. I removed the google maps plugin and now it's working correctly.

Any updates on this?

Hello everybody, I am working hard on this problem. Basically we have decided to build the geolocator from scratch and fix multiple problems at once.

Points that will be included are:

  • Fix permission issues;
  • Make sure the getCurrentLocation is retrieved within a reasonable time;
  • Add timeout to getCurrentLocation and getPositionStream methods, so that if acquiring the location takes longer then expected the request will timeout and you can restart the request;
  • Improve potential error messages;
  • Move to federated plugin structure so we are ready for web support;
  • Update to Android v2 plugin;

First step to take was to move out the geocoding features and host them in their own plugin (which is now available on pub.dev.

Second step was to create and unit-test all the necessary Dart code, which is now ready and can be viewed on the federated_plugin branch.

The next steps are to add iOS and Android implementations and fix the example app. This is what I am working on now, hopefully I will be able to finish everything in the coming two weeks (please keep in mind that I also need to do this in spare time ;)).

Anyway I want to thank everybody for there patience and feedback, please hang on just a little bit longer.

@mvanbeusekom
That's good news. I'm glad you're taking the time to provide us with this plugin.

A big thank you goes out to you!

I look forward to the following updates.

Thanks and best regards

Nice! Let us know when it's released so we can test.

For a temporary workaround you can check the status at the device with the method GeolocationStatus checkGeolocationPermissionStatus(). If the location is off, this method returns "disabled". Then you do not need to call the getCurrentPosition() method.

Example:

  Future<Position> getCurrentPosition() async {
    Position position;
    GeolocationStatus status = await _geolocator.checkGeolocationPermissionStatus(); 

    if (status != GeolocationStatus.disabled) {
      position = await _geolocator.getLastKnownPosition();

      if (position == null && status == GeolocationStatus.granted) {
        position = await _geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.high,
          locationPermissionLevel: GeolocationPermission.locationWhenInUse,
        );
      }
    }

    return position;
  }

Little update here, this morning I have pushed a new update to the federated_plugin branch which includes full support on iOS including a Flutter example App.

We have also started working on Android which supports checking permission status, we'll be implementing requesting permissions and handling location services now.

Feel free to check out the code or even try to integrate is in a test app and run on iOS. Note that is includes quite a lot of breaking changes which will all be documented. For now I just wanted to let everybody know that there is progress although it takes some time. Again thanks for all your patience.

Little update here, this morning I have pushed a new update to the federated_plugin branch which includes full support on iOS including a Flutter example App.

We have also started working on Android which supports checking permission status, we'll be implementing requesting permissions and handling location services now.

Feel free to check out the code or even try to integrate is in a test app and run on iOS. Note that is includes quite a lot of breaking changes which will all be documented. For now I just wanted to let everybody know that there is progress although it takes some time. Again thanks for all your patience.

Thanks for working hard on this. Will you be updating the geolocator package at pub.dev with this change?

Also is this the file for the example you mentioned above: position_updates_example_widget.dart?

Thanks for working hard on this. Will you be updating the geolocator package at pub.dev with this change?

Also is this the file for the example you mentioned above: position_updates_example_widget.dart?

No I won’t be publishing to pub.dev as of yet. This is a whole rework of the geolocator plugin and does not support Android yet. Once Android and the documentation is finished I will release it on pub.dev.

Yes this widget is part of the example app and demonstrates how you could listen for position updates.

Hi,

Thanks for this package.

Any chance to complete all above mentioned tasks for Android in this week ?

Any update on this?

Only waiting for location lagging when request for very first time.

Any updates on when the reworked version will be released? @mvanbeusekom

@dalmia007, I don’t have a date yet but progress being made. I have added rudimentary support for Android on the branch feature/federated_android. It contains requesting permissions, getting last known location, getting the current location and location updates all using the fused location provider client (part of the Google Play Services).

I am still working on the following:

Android specific:

  • Implementation for the above features when Google Play Services are not available;
  • Automatically resolve issues when location services are not enabled;

General:

  • Update the documentation

Feel free to check it out here

@mvanbeusekom thank you so much for the update! πŸ‘

Hi everybody,

I am happy to announce the I (finally) released version 6.0.0-rc.1 which should get rid of all these problems.

I would really appreciate if you could give it a try and give me your feedback.

I am sorry to tell this but it crashed twice now, enough to revert to 4.0.3 already.

E/AndroidRuntime(19881): java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=24, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.packagename.consumer.app/com.packagename.consumer.app.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.baseflow.geolocator.permission.PermissionResultCallback.onResult(com.baseflow.geolocator.permission.LocationPermission)' on a null object reference

Happened when I pressed allow grant on the dialog and also when I pressed deny. Let me know if I missed something.

@Dohmanlechx just making sure, did you get this on 6.0.0-rc.x or on the 5.3.2 version?

I did get this on 6.0.0-rc.1 (the IDE asked me to "update" to 5.3.2+2, FYI)

@Dohmanlechx thanks to your feedback I did find an issue. Apparently in your case the geolocator is getting feedback from another plugin (I am guessing you are using the permission_handler to handle permissions since the requestCode == 24 which is the same as the permission_handler) which it tries to process which obviously fails. In these cases the geolocator should simply ignore those messages since they don't belong to the geolocator. I will fix this today and release a new release candidate.

Thanks for your feedback!

Oh, indeed, we are using permission_handler. Good find!

All credits go to you @Dohmanlechx ;). Thanks to your feedback I was able to discover this bug and will be able to release a new version in soon.

@Dohmanlechx I have just release version 6.0.0-rc.3 which should fix the bug you experienced.

Very cool, tested carefully on the Android Emulator, granting & denying, manipulating the location, worked perfectly. Worked fine on my real Android device as well.

But no system request is showing for the iOS Simulator at all, guess it's intended? However, it won't crash at least and the app works as wished without any location available. Unfortunately still not able to test on my iPhone due to Xcode connection problem and I don't want to deploy a build to TestFlight just to test now. Will let you know as soon as I've tested on iPhone.

But so far, so good!

Thank you very much for the extensive testing @Dohmanlechx, it is very much appreciated!

The plugin indeed doesn't show a service request on iOS, since there is no (public) API to do so. The only option we have here is to manually show the user a message explaining how to update the settings manually. We do have an option to redirect the user to the Settings app (by calling the openAppSettings() or openLocationSettings() methods). I have documented this more detailed in the README.md file.

I regret to inform this but it worked like a disaster on my iPhone XS Max, OS 13.6.1.

First time fetching the position worked just like the old version, returned correct position but it still took 7-8 seconds.

But from the second time and further it just kept throwing instantly. I had to change from Exception err to dynamic err due to:
_Unhandled Exception: type β€˜_TypeError’ is not a subtype of type β€˜Exception’_.

I'm getting those when it's failing (after the first time fetching):

2020-08-26 14:01:45.670206+0200 Runner[4565:206487] flutter: Could not fetch location: Bad state: No element
2020-08-26 14:01:45.670416+0200 Runner[4565:206487] flutter: Could not fetch location: Instance of β€˜NoLocationFoundException’

(NoLocationFoundException is my custom class)

_Bad state: No element_ isn't telling much unfortunately... beneath is my code:

static Future<void> _getUserLocation({bool isSneaky = false}) async {

  void _throw(dynamic err) {
    print("Could not fetch location: $err");
    if (!isSneaky) Fluttertoast.showToast(msg: getTranslation("location_fetch_error"));
    throw NoLocationFoundException();
  }

  await GeolocatorPlatform.instance
      .getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high,
        timeLimit: const Duration(seconds: _TIMEOUT_DELAY),
      )
      .then((position) => _userLatestPosition = position)
      .catchError(
    (err) {
      // Debug only, remove later
      Fluttertoast.showToast(msg: "error: $err");

      if (err is TimeoutException) {
        GeolocatorPlatform.instance.getLastKnownPosition().then((position) {
          if (position == null) _throw(err);
          return position;
        }, onError: (err) {
          _throw(err);
        });
      } else if (err is PermissionDeniedException) {
        XxlPermissionsHandler.request(Permission.location);
      } else {
        _throw(err);
      }
    },
  ).catchError((err) => _throw(err));
}

I sincerely hope you can reproduce this on your iPhone.

@Dohmanlechx, thank you for the extensive feedback, I think I found the problem here. Now I need to find a good way to fix it ;)

In short the getCurrentPosition method calls the getPositionStream and takes the first element and then closes the stream. The problem is that the getPositionStream has code like this:

    if (_positionStream != null) {
      return _positionStream;
    }

Which you can guess causes the Bad state: No element exception when calling the getCurrentPosition for the second time, because it will be calling first on an already closed stream. I will be working on this and release a new candidate soon.

@Dohmanlechx, you issue where you get the "Bad state: No element" should have been fixed in 6.0.0-rc.4 which I just published. I was not able to reproduce the problem, but I was able to make sure that the getCurrentPosition will use a new stream when you call it a second (and any subsequent) time.

I would really appreciate it is you can give it another try and let me know if it works.

On thing I noticed is that you directly use the GeolocatorPlatform.instance.<some_method>, by doing this you are by passing any logic that is located in the geolocator package and go straight to the default implementation that is in the geolocator_platform_instance package. As for now there is no specific implementation in the geolocator package but it is still better not to by pass it.

If you import the geolocator package you should be able to directly call the global methods, for example:

import 'package:geolocator/geolocator.dart';

final position = await getCurrentPosition();

If you run into collisions or simply like to prefix the global methods you can add an alias to the import, like so:

import 'package:geolocator/geolocator.dart' as geolocator;

final position = await geolocator.getCurrentPosition();

Thanks, I also changed the code according to your suggestions.

The crash is gone now but unfortunately, it's still too unstable. 3 out of 10 times it's extremely fast (really wish it was 10 out of 10 times), but 7 out of 10 times the Time Limit (10 seconds) exceeds and the function throws. Did you test on your iPhone, spamming the getCurrentPosition()? I tested on iPhone XS Max, OS 13.6.1.

_4.0.3_ is slow but stable
_6.0.0-rc.4_ is fast but unstable

But no worries, this is completely okay and absolutely no disaster for us, especially since I wrote own time limit for the version 4.0.3.

@Dohmanlechx glad to hear the crash is solved, that is something at least ;)

I am really interested in why you are still receiving slow updates since I cannot reproduce it. I created a very simple demo App to try it out:

main.dart:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<Position> _positions = <Position>[];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: ListView.builder(
          itemCount: _positions.length,
          itemBuilder: (BuildContext context, int index) {
            return ListTile(title: Text(_positions[index].toString()),);
          },),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () => getCurrentPosition().then((position) {
            setState(() {
              _positions.add(position);
            });
          }),
        ),
      ),
    );
  }
}

Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>geolocator_issue</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>$(FLUTTER_BUILD_NAME)</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>$(FLUTTER_BUILD_NUMBER)</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIViewControllerBasedStatusBarAppearance</key>
    <false/>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>The example App requires access to the device's location.</string>
</dict>
</plist>

So each time I hit the floating action button getCurrentPosition is called and the result is added to the ListView. I have tested this App on my personal iPhone 7, my wife's iPhone 6 and the simulator (all running the latest iOS version) but I can spam the button and the location is returned almost immediately. I am really puzzled why you have a different experience. Maybe you can test this sample code and see if you still have the same problem?

I really admire your persistence. I created a new project and used your codes, almost broke the iPhone screen by spamming the button, the location returned immediately all the time. Awesome! Tomorrow I will try find time to troubleshoot in our code, beginning with running getCurrentPosition() directly in the Widget and then move it further and further away until its intended place in order to find the culprit. I suspect it is because the permissions plugin, but we will see.

Thanks for the feedback and the kind words, really appreciate it. I put a lot of effort in rebuilding the geolocator and this issue was the one that really made me decide to start it, so I would really like it to be good this time ;)

Please let me know how it goes and if I can help.

getCurrentPosition().then((position) {
   print(position);
}).catchError((err) {
   print(err);
});

Tried this directly in the Widget and every time I clicked, a location was logged on the console! So it's definitively our code. So it's on us now, thanks for everything!

Though, this _sometimes_ happens while fetching position:

I/flutter (  393): ══║ EXCEPTION CAUGHT BY SERVICES LIBRARY β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
I/flutter (  393): The following PlatformException was thrown while de-activating platform stream on channel
I/flutter (  393): flutter.baseflow.com/geolocator_updates:
I/flutter (  393): PlatformException(error, No active stream to cancel, null)
I/flutter (  393): 
I/flutter (  393): When the exception was thrown, this was the stack:
I/flutter (  393): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:572:7)
I/flutter (  393): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:161:18)
I/flutter (  393): <asynchronous suspension>
I/flutter (  393): #2      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:334:12)
I/flutter (  393): #3      EventChannel.receiveBroadcastStream.<anonymous closure> (package:flutter/src/services/platform_channel.dart:554:29)
I/flutter (  393): #4      EventChannel.receiveBroadcastStream.<anonymous closure> (package:flutter/src/services/platform_channel.dart:551:18)
I/flutter (  393): #18     MethodChannelGeolocator.getPositionStream.<anonymous closure> (package:geolocator_platform_interface/src/implementations/method_channel_geolocator.dart:135:13)
I/flutter (  393): (elided 24 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
I/flutter (  393): ════════════════════════════════════════════════════════════════════════════════════════════════════

@mvanbeusekom I am not able to get the position at all using the newest 6.0.0+1 version. Tried on iOS simulator, Android emulator API 29, physical OnePlus 6. Timeout is thrown every time.

image

image

I don't know what else I can add here to support you in finding the issue, getCurrentPosition returns timeout or just hangs if timeLimit parameter is not specified. I have tried different location accuracies. Does anyone have this issue?

Version 5.3.2+2 works fine on iOS simulator (with the custom location specified), Android real device and Android emulator

@mvanbeusekom , I've read through all of these, and I am upgrading to the latest version to fix the 10 second delay issue.

Maybe I'm missing something, but there's something that I can no longer do in the new version (geocoding).
I used to be able to manually set a Position to the city center (in case the user denies location), by doing the following:

Position userLocation;
List<Placemark> listAddresses = [];
if(permission.toString() != "PermissionStatus.granted"){
        listAddresses = await placemarkFromAddress("$city, $state");
         userLocation = listAddresses[0].position;
    }else{
getCurrentPosition...
}

Now, it seems _placemarkFromAddress_ has been changed into _locationFromAddress_, so I tried to adapt doing the following changes in my formula:

Position userLocation;
List<Location> listAddresses = [];
if(permission.toString() != "PermissionStatus.granted"){
        listAddresses = await locationFromAddress("$city, $state");
         userLocation = listAddresses[0].position;
    }else{
getCurrentPosition...
}

But I'm getting the following error:

A value type 'Location' can't be assigned to a variable of type 'Position'.

How can I convert location into Position, or ultimately, in case the user denies the location, how can I now set his Position to his city center?

Thanks.

I updated to the newest version, fixed the problem for me πŸ‘πŸ‘πŸ‘

Was this page helpful?
0 / 5 - 0 ratings

Related issues

long1eu picture long1eu  Β·  4Comments

joesnarky picture joesnarky  Β·  3Comments

hectorAguero picture hectorAguero  Β·  5Comments

DineshKachhot picture DineshKachhot  Β·  7Comments

samo92 picture samo92  Β·  6Comments