Skip to content

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

Closed
@jaimisdomadiya

Description

@jaimisdomadiya

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions