flutter-geolocator icon indicating copy to clipboard operation
flutter-geolocator copied to clipboard

[Bug]: Geolocator.getCurrentPosition hangs after app restart

Open corepuncher opened this issue 8 months ago • 9 comments

Please check the following before submitting a new issue.

Please select affected platform(s)

  • [x] Android
  • [ ] iOS
  • [ ] Linux
  • [ ] macOS
  • [ ] Web
  • [ ] Windows

Steps to reproduce

In an Android app, request GeoLocator.getCurrentPosition().

First time is fast. I use "medium".

Then, either kill the app and re-open, or, do a hot reload if debugging.

Second time, or perhaps one or two times after, the app will hang during getCurrentPosition.

Expected results

It should again work fast after killing the app and restarting.

Actual results

After opening the app, closing the app, then re-opening, (maybe cycle that 1-3 times), Geolocator will hang for 16-20 seconds before finally getting a position.

Code sample

Code sample
  Future<Position> getCurrentLocation() async {
    const locationSettings = LocationSettings(
      accuracy: LocationAccuracy.medium, // Medium accuracy (100-500m)
    );
    final position = await Geolocator.getCurrentPosition(
      locationSettings: locationSettings,
    );
    return position;
  }

Screenshots or video

Screenshots or video demonstration

[Upload media here]

Version

13.0.2

Flutter Doctor output

Doctor output

[√] Flutter (Channel beta, 3.32.0-0.1.pre, on Microsoft Windows [Version 10.0.22],
    locale en-US) [778ms]
    • Flutter version 3.32.0-0.1.pre on channel beta at C:\Flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision eeb81b9a8a (4 days ago), 2025-04-11 12:11:52 -0700
    • Engine revision 72ee26e314
    • Dart version 3.8.0 (build 3.8.0-278.1.beta)
    • DevTools version 2.45.0

[√] Windows Version (11 Home 64-bit, 22H2, 2009) [4.9s]

[√] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [2.6s]
    • Platform android-35, build-tools 35.0.0
    • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 17.0.9+0--11185874)
    • All Android licenses accepted.

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.13.6) [403ms]
    • Visual Studio Community 2022 version 17.13.35931.197
    • Windows 10 SDK version 10.0.22000.0

[√] Android Studio (version 2023.2) [25ms]
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.9+0--11185874)

[√] VS Code (version 1.99.2) [23ms]
    • Flutter extension version 3.108.0

[√] Network resources [458ms]
    • All expected network resources are available.

• No issues found!```

</details>

corepuncher avatar Apr 15 '25 22:04 corepuncher

@corepuncher,

How did you test this, on a simulator? Or a real device?

Kind regards,

TimHoogstrate avatar Apr 16 '25 09:04 TimHoogstrate

Real device. Galaxy S23+

At first I thought it was happening only when hot reloading during debugging.

However, when running the app alone on the device (debug OR release build), startup was also delayed after closing the app and immediately restarting.

corepuncher avatar Apr 16 '25 17:04 corepuncher

Can confirm this is an issue. This doesn't happen if I set LocationAccuracy.high

YarosMallorca avatar Apr 19 '25 18:04 YarosMallorca

I noticed that when the long hang/timeout occurs, there is no "location" symbol in the top status bar. Once the symbol finally appears, everything proceeds quickly. I wonder what it is "waiting" for?

Also, can confirm that "high" does not have the issue. But Low and Medium both do. "reduced" does NOT have the issue either.

"hang" times are typically 10-20 seconds.

corepuncher avatar May 06 '25 12:05 corepuncher

I'am not sure about your testing conditions but can you post the LocationSettings that you use, maybe I can try to reproduce this? I cannot reproduce this on my own testing device. Also check if the device has Wifi or a simcard, because otherwise perhaps only the GPS is used, and this might take some time to warmup.

Kind regards,

TimHoogstrate avatar May 19 '25 11:05 TimHoogstrate

I do have wifi and sim card, it uses that (no location icon appears on the status bar).

YarosMallorca avatar May 19 '25 13:05 YarosMallorca

@TimHoogstrate

  1. My S23 device has no sim card. Only wifi.

  2. My code is:

  Future<Position> getCurrentLocation() async {
    const locationSettings = LocationSettings(
      accuracy: LocationAccuracy.medium,
    );
    final position = await Geolocator.getCurrentPosition(
      locationSettings: locationSettings,
    );
    return position;
  }


Manifest:

   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
   <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  1. To reproduce:

A) open app, always works fast the first time. B) Immediately close the app and re-open. C) Hangs 15-20 seconds at the code above. If it does not hang on re-open, close and open again. D) Even in release version, not a debugging issue (although I used debug to place print statements to see where hang is). E) I use medium, but low also has the issue. High has no issue, but I'd rather not use high.

If you cannot re-produce, you could load up one of your geolocator files with 'got here 1' print statements, then send it to me and I'll replace and run it and figure out where it hangs at?

corepuncher avatar May 20 '25 16:05 corepuncher

@TimHoogstrate

Did some testing...

TEST A

  • Removed ACCESS_FINE_LOCATION from manifest completely.

  • Reinstalled app. The permission modal shows only the approximate location "map circle", and I choose allow while using.

  • No hanging using LocationAccuracy.medium. Interestingly, while my latitude is accurate to 3 decimals, my LONGITUDE is definitely "off" compared to reality by about .01. For example:

    45.36136136136136 <- interesting repeating pattern..... -100.49034140653207


TEST B

  • THEN, I put ACCESS_FINE_LOCATION back into manifest (along with COARSE).

  • Reinstalled app, and when permission modal shows, I left it on the first "map circle" which is fine location. I have never selected the approximate one on the right when having both as a choice.

  • Bug reproduced with LocationAccuracy.medium. First run, app is fast. Close, restart, hangs on geolocator. Lat lon printed:

    45.3611063 -100.5008222

And then just for reference, although I will not be using high, the lat/lon printed is:

45.3610212 -100.5007815

corepuncher avatar May 20 '25 17:05 corepuncher

My workaround is currently this and seems to work well.

Medium is my first choice because it is very fast and good enough. Typically 50-100 ms.

High can take 2-3 seconds.

And then a tertiary fallback to "reduced" since that does not seem to have the hanging problem. Just in case user does not allow high accuracy permissions.

Future<Position> getCurrentLocation() async {
   const mediumSettings = LocationSettings(accuracy: LocationAccuracy.medium);
   const highSettings = LocationSettings(accuracy: LocationAccuracy.high);
   const reducedSettings = LocationSettings(accuracy: LocationAccuracy.reduced);

   try {
     if (kDebugMode) print('==> GEO: Updating with medium accuracy...');
     return await Geolocator.getCurrentPosition(locationSettings: mediumSettings)
         .timeout(const Duration(milliseconds: 1000));
   } on TimeoutException catch (_) {
     if (kDebugMode) print('==> GEO: medium timed out, trying high...');
   } catch (e) {
     if (kDebugMode) print('==> GEO: medium error $e, trying high...');
   }

   try {
     if (kDebugMode) print('==> GEO: trying high fallback...');
     return await Geolocator.getCurrentPosition(locationSettings: highSettings).timeout(const Duration(seconds: 5));
   } on TimeoutException catch (_) {
     if (kDebugMode) print('==> GEO: high timed out, trying reduced...');
   } catch (e) {
     if (kDebugMode) print('==> GEO: high error $e, trying reduced');
   }

   if (kDebugMode) print('==> GEO: Using reduced final fallback');
   return await Geolocator.getCurrentPosition(locationSettings: reducedSettings).timeout(const Duration(seconds: 10));
 }

corepuncher avatar Jul 02 '25 01:07 corepuncher