3

My code is:

class _LoadingScreenState extends State<LoadingScreen> {
  void getLocation() async {
    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.low);
    print(position);
  }

I added to the Android manifest the following:

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

Android emulator, GPS is on.

After trying to access geolocation I receive an error:

E/flutter ( 5034): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: User denied permissions to access the device's location.
E/flutter ( 5034): #0      MethodChannelGeolocator.getCurrentPosition (package:geolocator_platform_interface/src/implementations/method_channel_geolocator.dart:127:7)
E/flutter ( 5034): <asynchronous suspension>
E/flutter ( 5034): #1      _LoadingScreenState.getLocation (package:clima/screens/loading_screen.dart:11:25)
E/flutter ( 5034): <asynchronous suspension>

In Settings - Security & location - Privacy - Location - App level permissions my app's permission is off.

After turning it on I receive a request:

enter image description here

Why is it happening?

Here https://pub.dev/packages/geolocator it is stated that

The geolocator will automatically try to request permissions when you try to acquire a location through the getCurrentPosition or getPositionStream methods. We do however provide methods that will allow you to manually handle requesting permissions.

Aren't the permissions supposed to be set as a result of the selection in the permission request?

I have almost the same problem with iOS: In the Settings - Privacy - Location Services - my app permission is set to While Using. After trying to access geolocations I receive to dialog window but an error:

[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: User denied permissions to access the device's location. #0 MethodChannelGeolocator.getCurrentPosition (package:geolocator_platform_interface/src/implementations/method_channel_geolocator.dart:127:7) #1 _LoadingScreenState.getLocation (package:clima/screens/loading_screen.dart:11:25)

but why?

Kosh
  • 960
  • 2
  • 13
  • 28
  • 1
    You need to request the actual pop up permission to the user. It's not enough with adding the permission over the Manifest. Android never auto request permissions, is a manual process (or, sometimes libraries will request for you to avoid doing the code) – Mariano Zorrilla Jan 17 '22 at 15:46
  • I suggest using [permission_handler](https://pub.dev/packages/permission_handler) package to get user's permission. – Peter Koltai Jan 17 '22 at 18:36

2 Answers2

9

I'm late but it can be useful for other developers.

bool serviceEnabled;
LocationPermission permission;

// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();


permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) {
        Get.snackbar('', 'Location Permission Denied');
        // Permissions are denied, next time you could try
        // requesting permissions again (this is also where
        // Android's shouldShowRequestPermissionRationale
        // returned true. According to Android guidelines
        // your App should show an explanatory UI now.
        return Future.error('Location permissions are denied');
      }
    }

if (permission == LocationPermission.deniedForever) {
 // Permissions are denied forever, handle appropriately.
 return Future.error(
     'Location permissions are permanently denied, we cannot request permissions.');
}
return Geolocator.getCurrentPosition(
    desiredAccuracy: LocationAccuracy.high);

Just remove the isServiceEnabled check, when you request permission, it will automatically ask the user to enable the device location service.

Elidor00
  • 1,271
  • 13
  • 27
Mehroze Zaidi
  • 125
  • 1
  • 9
3

As a starter you can try this code:

void getLocation() async {
    LocationPermission permission;
    permission = await Geolocator.checkPermission();
    permission = await Geolocator.requestPermission();
    if( permission== LocationPermission.denied){
         //nothing
    }
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
    print(position);
  }

But better format is using Future and async:

Future<Position> determinePosition() async {
    bool serviceEnabled;
    LocationPermission permission;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    permission = await Geolocator.requestPermission();

      if (permission == LocationPermission.denied) {
        return Future.error('Location permissions are denied');
      }


    if (permission == LocationPermission.deniedForever) {
      return Future.error(
          'Location permissions are permanently denied, we cannot request permissions.');
    }
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
    print(position);

    return await Geolocator.getCurrentPosition();
  }