6

I'm trying to request for location permission on the app that I'm working on. It works perfectly on an Android device but not prompting anything on iOS. The target iOS version is 11 and packages that I use are geolocator: ^5.3.1 and permission_handler: ^5.0.0+hotfix.5.

Here is my code.

Here is my utility function to request for permission if the status is not granted.

Future<PermissionStatus> getDeviceLocationPermission() async {
 final PermissionStatus permissionStatus =
  await Permission.locationWhenInUse.status;

  if (permissionStatus != PermissionStatus.granted) {
    await Permission.locationWhenInUse.request();
  }

  return permissionStatus;
}

Here is my utility function to collect the position details.

Future<Position> getDeviceCurrentLocation(
    {@required PermissionStatus permissionStatus}) async {
  Position position;
  Geolocator geolocator = Geolocator()..forceAndroidLocationManager;

  if (permissionStatus == null) {
    return null;
  }

  if (permissionStatus == PermissionStatus.granted) {
    position = await geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
  }

  return position;
}

And this is how I access these utilities inside a stateful widget.

getDeviceLocationPermission().then((permissionStatus) {
      print(permissionStatus);
      getDeviceCurrentLocation(permissionStatus: permissionStatus)
          .then((position) {
        print(position);
      });
    });

Here are my info.plist permissions for the location service.

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location when open and in the background.</string>

On an iOS device, it doesn't prompt a dialog asking to allow or deny access and also returns a null value.

Please ask if there is any other information needed. Can someone please help me with this? Thanks in Advance!

SUPARNA SOMAN
  • 2,311
  • 3
  • 19
  • 35

3 Answers3

14
  1. Add this to your info.plist file.

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Location permission is required.</string>
    
  2. Add PERMISSION_LOCATION=1 to your podfile. Check the following:

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        flutter_additional_ios_build_settings(target)
    
        target.build_configurations.each do |config|
          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
            '$(inherited)',
    
            ## Add this line
             'PERMISSION_LOCATION=1'
          ]
        end
      end
    end
    
  3. Request the permission:

    var status = await Permission.locationWhenInUse.request();
    
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
0

I followed your code as well as the one they gave in package permission_handler. Ran both and reproduced the issue in your code.

The problem could be solved as below. :

Created a generic permission values list.

List<Permission> lp = Permission.values;

Tweaked function getDeviceLocationPermission as below :

Future<PermissionStatus> getDeviceLocationPermission() async {

    Permission _permission = lp.elementAt(5); // 5 = location in use permission

    // The following line then prompts the required alert dialog
    final PermissionStatus permissionStatus = await _permission.request(); 


    /* final PermissionStatus permissionStatus = await Permission.locationWhenInUse.status;

    if (permissionStatus != PermissionStatus.granted) {
      await Permission.locationWhenInUse.request();
    }*/

    return permissionStatus;
}

Note : The above is minimal code required to fix your issue. Depending on your requirement, you might want to uncomment the if condition.

In my opinion, the better package to use is location package. One package gives you permission handler as well as latlongs and the code is pretty straight-forward. See below :

var location = new Location();
currentLocation = await location.getLocation(); // This prompts the dialog
// __If condition and all
debugPrint(currentLocation.latitude.toString());
Sukhi
  • 13,261
  • 7
  • 36
  • 53
0

If you want to use geolocator you don't need permission permission_handler. because geolocator has _getLocationPermission() method and this method will get location permission internally. also, I found that getting permission in ios simulator not working correctly. you can check this issue too. so you can simplify your code like this:

Future<Position> getDeviceCurrentLocation() async {
  Position position;
  Geolocator geolocator = Geolocator()..forceAndroidLocationManager;

  position = await geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);


  return position;
}

and

getDeviceCurrentLocation()
          .then((position) {
        print(position);
      });
Payam Zahedi
  • 827
  • 7
  • 20