Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: App delay and crash on second launch using geolocator package #1603

Open
3 of 8 tasks
jaimisdomadiya opened this issue Nov 12, 2024 · 5 comments
Open
3 of 8 tasks
Assignees

Comments

@jaimisdomadiya
Copy link

Please check the following before submitting a new issue.

Please select affected platform(s)

  • Android
  • iOS
  • Linux
  • macOS
  • Web
  • Windows

Steps to reproduce

Add the geolocator package to your Flutter project (version 13.0.1).
Implement location permission requests and retrieval in your main app file, as shown in the code sample.
Run the app on an Android device (Android 14 or others).
On the first launch, the location request works as expected.
Close the app completely (kill the process) and relaunch it.
Observe that on the second launch, the app either takes a long time to load or crashes.

Expected results

The app should retrieve the location data and proceed to the home screen within a reasonable time on all launches, including subsequent launches after being killed.

Actual results

On the second launch (after killing the app):

The app often takes a long time to retrieve location data and load the home screen, or
The app sometimes crashes, failing to load at all.

Code sample

Code sample
import 'package:flutter/material.dart';
import 'location_info.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await _checkLocationPermissions();
  runApp(MyApp());
}

Future<void> _checkLocationPermissions() async {
  try {
    if (await LocationInfo.checkAndRequestLocationPermission()) {
      if (!await LocationInfo.isLocationServicesOn() && !locationServicesOffNotified) {
        Get.rawSnackbar(message: LocaleKeys.location_services_are_off.tr);
        locationServicesOffNotified = true;
      }
    }
  } catch (e) {
    debugPrint("Error checking location permissions: $e");
  }
}
Code sample
import 'package:abs/config/environment_args.dart';
import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';

class LocationInfo {
  static Future<String?> getISOCountryCode() async {
    if (EnvironmentArgs.isAutomationTestModeEnabled) return null;

    try {
      // Check permission and services before attempting to get location
      if (!await checkAndRequestLocationPermission()) {
        debugPrint("Permission not granted for accessing location.");
        return null;
      }

      if (!await isLocationServicesOn()) {
        debugPrint("Location services are not enabled.");
        return null;
      }

      final position = await getCurrentLocation();
      return position != null ? _getISOCountryCodeFromPosition(position) : null;
    } catch (e) {
      debugPrint("Failed to get ISOCountryCode: $e");
      return null;
    }
  }

  static Future<bool> checkAndRequestLocationPermission() async {
    try {
      final _geolocatorPlatform = GeolocatorPlatform.instance;
      var permission = await _geolocatorPlatform.checkPermission();

      if (permission == LocationPermission.denied) {
        permission = await _geolocatorPlatform.requestPermission();
        if (permission == LocationPermission.denied) {
          debugPrint('Country config: location permission was denied');
          return false;
        }
      }

      if (permission == LocationPermission.deniedForever) {
        debugPrint('Country config: location services were permanently denied');
        return false;
      }

      return permission == LocationPermission.whileInUse || permission == LocationPermission.always;
    } catch (e) {
      debugPrint('Error in checkAndRequestLocationPermission: $e');
      return false;
    }
  }

  static Future<bool> isLocationServicesOn() async {
    try {
      final _geolocatorPlatform = GeolocatorPlatform.instance;
      return await _geolocatorPlatform.isLocationServiceEnabled();
    } catch (e) {
      debugPrint("Error checking location service status: $e");
      return false;
    }
  }

  static Future<Position?> getCurrentLocation() async {
    try {
      final _geolocatorPlatform = GeolocatorPlatform.instance;
      if (!await _handlePermission(_geolocatorPlatform)) {
        debugPrint("Insufficient permissions or location services are off.");
        return null;
      }
      return await _geolocatorPlatform.getCurrentPosition();
    } catch (e) {
      debugPrint("Failed to get current location: $e");
      return null;
    }
  }

  static Future<bool> _handlePermission(GeolocatorPlatform _geolocatorPlatform) async {
    try {
      if (!await _geolocatorPlatform.isLocationServiceEnabled()) {
        debugPrint('Location services are not enabled');
        return false;
      }

      var permission = await _geolocatorPlatform.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await _geolocatorPlatform.requestPermission();
        if (permission == LocationPermission.denied) {
          debugPrint('Location permission was denied');
          return false;
        }
      }

      if (permission == LocationPermission.deniedForever) {
        debugPrint('Location services were permanently denied');
        return false;
      }

      return true;
    } catch (e) {
      debugPrint("Error handling permissions: $e");
      return false;
    }
  }

  static Future<String?> _getISOCountryCodeFromPosition(Position _currentPosition) async {
    try {
      var placemarks = await placemarkFromCoordinates(_currentPosition.latitude, _currentPosition.longitude);
      return placemarks.isNotEmpty ? placemarks[0].isoCountryCode : null;
    } catch (e) {
      debugPrint('Error getting ISO country code from position: $e');
      return null;
    }
  }
}

Screenshots or video

Screenshots or video demonstration

[Upload media here]

Version

Geolocator Package Version: 13.0.1 play-services-location Version: 21.1.0

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.24.3, on macOS 14.4.1 23E224 darwin-arm64, locale en-IN)
    • Flutter version 3.24.3 on channel stable at /Users/jaimis/Developer/flutter-sdk/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2663184aa7 (9 weeks ago), 2024-09-11 16:27:48 -0500
    • Engine revision 36335019a8
    • Dart version 3.5.3
    • DevTools version 2.37.3

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
    • Android SDK at /Users/jaimis/Library/Android/sdk
    • Platform android-35, build-tools 35.0.0
    • ANDROID_HOME = /Users/jaimis/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15E204a
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • 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.10+0-17.0.10b1087.21-11572160)

[✓] Connected device (1 available)
    • sdk gphone64 arm64 (mobile)     • emulator-5554             • android-arm64  • Android 13 (API 33) (emulator)


[✓] Network resources
    • All expected network resources are available.
@TimHoogstrate
Copy link
Contributor

Dear @jaimisdomadiya,

It is possible that it takes some time to retrieve your location. Do you have a crashlog that we can take a look at?

Kind regards,

@TimHoogstrate TimHoogstrate self-assigned this Nov 13, 2024
@TimHoogstrate TimHoogstrate added the status: needs more info We need more information before we can continue work on this issue. label Nov 13, 2024
@jaimisdomadiya
Copy link
Author

jaimisdomadiya commented Nov 13, 2024

Hi team,

Thank you for your response. Here’s a detailed update regarding the issue:

Current Issue and Behavior

First Launch:

On the first launch, the app behaves as expected:

  1. It prompts the user for location permissions.
  2. The location is retrieved smoothly, and there’s no delay or crash.

Second Launch (App Relaunch After Forced Kill):

After closing (killing) the app and reopening it, the following behavior is observed:

  1. The app displays the splash screen but hangs there for over 20 seconds.
  2. Occasionally, after this delay, the app does eventually navigate to the home screen, but this behavior is inconsistent.
  3. At other times, the app crashes without reaching the main screen.

Terminal Logs
Below are the logs captured when the app is reopened after being killed:

  • D/FlutterGeolocator(15165): Flutter engine disconnected. Connected engine count 0
  • E/FlutterGeolocator(15165): Geolocator position updates stopped
  • D/FlutterGeolocator(15165): Stopping location service.
  • D/FlutterGeolocator(15165): Unbinding from location service.
  • D/FlutterGeolocator(15165): Destroying location service.
  • D/FlutterGeolocator(15165): Stopping location service.
  • D/FlutterGeolocator(15165): Destroyed location service.
  • D/FlutterGeolocator(15814): Creating service.
  • D/FlutterGeolocator(15814): Binding to location service.
  • D/FlutterGeolocator(15814): Flutter engine connected. Connected engine count 1
  • I/flutter (15814): Failed to source SIM carrier country code

@github-actions github-actions bot removed the status: needs more info We need more information before we can continue work on this issue. label Nov 13, 2024
@nigorora14
Copy link

nigorora14 commented Nov 22, 2024

The same thing happens to me, it works fine the first time, then you close the app and go back in and that's when it takes about 20 seconds or the app breaks.

The problem always occurs after accepting the location permissions and it only happens on Android

geolocator: ^13.0.2

  @override
  Widget build(BuildContext context) {
    final appRouter = ref.watch(appRouteProvider);
    ref.watch(requestPermissionsProvider);

    return MaterialApp.router(
      key: navigatorKey,
      supportedLocales: const [Locale('es'), Locale('en')],
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      debugShowCheckedModeBanner: false,
      routerConfig: appRouter,
    );
  }

///////

@Riverpod(keepAlive: true)
Future<void> requestPermissions(ref) async {
  if (await Permission.location.request().isGranted) {
    print('Permiso otorgado');
  } else {
    print('Permiso denegado');
  }
}

@julvikramsupandi
Copy link

+1

1 similar comment
@anandyadav21219
Copy link

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants