Search code examples
androidfluttergpslocation

How to solve "gps" location provider requires ACCESS_FINE_LOCATION permission


I'm working on a flutter application that use location package to track user position, It was worked fine, but by same cases I have upgrade the location package to 4.0.0 (from 3.0.1) but now a problem like appear:

E/AndroidRuntime(12224): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(12224): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) E/AndroidRuntime(12224): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980) E/AndroidRuntime(12224): Caused by: android.os.RemoteException: Remote stack trace: E/AndroidRuntime(12224): at com.android.server.LocationManagerService.checkResolutionLevelIsSufficientForProviderUseLocked(LocationManagerService.java:1979) E/AndroidRuntime(12224): at com.android.server.LocationManagerService.hasGnssPermissions(LocationManagerService.java:1752) E/AndroidRuntime(12224): at com.android.server.LocationManagerService.addGnssDataListener(LocationManagerService.java:3053) E/AndroidRuntime(12224): at com.android.server.LocationManagerService.registerGnssStatusCallback(LocationManagerService.java:2991) E/AndroidRuntime(12224): at android.location.ILocationManager$Stub.onTransact(ILocationManager.java:583)

I have correctly added the permission in android manifest file:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Also I have checked for the permission before launching the location listener but the problem is allows exist.

My LocationService:

class LocationService with ChangeNotifier {
  static LocationService _instance;

  factory LocationService() => _instance ??= LocationService._internal();
  LocationService._internal();

  bool hasPermission = false;
  bool hasService = false;
  String lastError;
  Location _locationService = Location();

  LatLng _currentLocation = LatLng(0, 0);

  set currentLocation(LatLng value) {
    _currentLocation = value;
    notifyListeners();
  }

  LatLng get currentLocation => _currentLocation;

  @override
  void dispose() {
    super.dispose();
  }

  void init() async {
    await _locationService.changeSettings(
      accuracy: LocationAccuracy.high,
      interval: 1000,
    );
    try {
      hasService = await _locationService.serviceEnabled();
      if (hasService) {
        print('Location service is enabled');

        var permission = await _locationService.requestPermission();
        hasPermission = permission == PermissionStatus.granted;

        if (hasPermission) {
          print('Location service has permission');
          final location = await _locationService.getLocation();
          currentLocation = LatLng(location.latitude, location.longitude);
          _locationService.onLocationChanged.listen((data) =>
              currentLocation = LatLng(data.latitude, data.longitude));
        } else
          throw geo.PermissionDeniedException(null);
      } else {
        hasService = await _locationService.requestService();
        if (hasService) {
          init();
          return;
        } else
          throw geo.LocationServiceDisabledException();
      }
    } catch (e) {
      lastError = e.toString();
      String message;
      if (e.runtimeType == geo.PermissionDeniedException)
        message = 'Veuillez vérifier l\'autorisation d\'activation';
      else if (e.runtimeType == geo.LocationServiceDisabledException)
        message = 'Veuillez activer votre service GPS';
      AlertUtils.showConfirmDialog(e.toString(),
          content: message, okLabel: 'Settings', okFunction: () async {
        Get.back();
        if (e.runtimeType == geo.PermissionDeniedException) {
          if (await geo.Geolocator.openAppSettings())
            AlertUtils.showConfirmDialog('Réessayez?', okLabel: 'Réessayez?',
                okFunction: () {
              Get.back();
              init();
            });
          else
            AlertUtils.showConfirmDialog(
                'Impossible d\'activer l\'autorisation automatiquement, merci de le faire manuellement.');
        } else if (e.runtimeType == geo.LocationServiceDisabledException) {
          if (await geo.Geolocator.openLocationSettings())
            AlertUtils.showConfirmDialog('Réessayez?', okLabel: 'Réessayez?',
                okFunction: () {
              Get.back();
              init();
            });
          else
            AlertUtils.showConfirmDialog(
                'Impossible d\'activer le GPS automatiquement, merci de le faire manuellement.');
        }
      });
    }
  }
}

Thanks for your help


Solution

  • I found that the problem is with setting to configuration of my localization pluggin before checking at the permission, soo simply I have moved it inside the if condition like:

     if (hasPermission) {
              print('Location service has permission');
              await _locationService.changeSettings(
                accuracy: LocationAccuracy.high,
                interval: 1000,
              );
              final location = await _locationService.getLocation();
              currentLocation = LatLng(location.latitude, location.longitude);
              _locationService.onLocationChanged.listen((data) =>
                  currentLocation = LatLng(data.latitude, data.longitude));
            } else
              throw geo.PermissionDeniedException(null);