Granting location permission with Flutter at iOS

15,411

Have you tried using https://pub.dev/packages/permission?

Sample methods:

import 'package:permission/permission.dart';

var permissions = await Permission.getPermissionsStatus([PermissionName.Calendar, PermissionName.Camera]);

var permissionNames = await Permission.requestPermissions([PermissionName.Calendar, PermissionName.Camera]);

Permission.openSettings;

But like the comments say, if the permission is rejected, then you have to manually go to the settings to enable it. For more understanding, see medium/Requesting Location Permissions in iOS (March 2018)

Users have only one chance to respond to these alerts, so you want to make your request at the right time and provide a good reason for it. If the user doesn’t allow access, they’ll need to go to the settings to enable location access.

Share:
15,411
Hasan A Yousef
Author by

Hasan A Yousef

Industrial Engineer, with a slogan "If you can automate it, do not do it". Interested in all types of automation that facilitate life. Work officially as Supply Chain Manager, where Data is the main driver of availability. Combining my IT skills and interest with my work expertise, proud to deliver the best possible results for my organization.

Updated on June 04, 2022

Comments

  • Hasan A Yousef
    Hasan A Yousef almost 2 years

    The below code run smoothly at Android, but stuck at iOS, when I click the map icon, the system should update my location:

    import 'package:flutter/material.dart';
    import 'package:location/location.dart';
    import 'package:flutter/services.dart';
    import 'package:simple_permissions/simple_permissions.dart';
    
    class LocationState extends State {
    
      String _loca_ext;
    
      Location _location = new Location();
      Map<String, double> _currentLocation;
    
      String error;
    
      @override
      void initState() {
        super.initState();
    
        setState(() {
          _loca_ext = 'Clik to update location';
        });
    
      }
    
      // Platform messages are asynchronous, so we initialize in an async method.
      _getLocation() async {
        Map<String, double> location;
        // Platform messages may fail, so we use a try/catch PlatformException.
        try {
          await SimplePermissions.requestPermission(Permission.AccessFineLocation);
          location = await _location.getLocation();
          error = null;
        } on PlatformException catch (e) {
          if (e.code == 'PERMISSION_DENIED') {
            error = 'Permission denied';
          } else if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
            error =
            'Permission denied - please ask the user to enable it from the app settings';
          }
          location = null;
        }
        print("error $error");
    
        setState(() {
          _currentLocation = location;
          _loca_ext = ('${_currentLocation["latitude"]}, ${_currentLocation["longitude"]}' ?? 'Grant location Access');
          print(_currentLocation);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Baby Name Votes')),
          body: _buildBody(context),
        );
      }
    
      Widget _buildBody(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(5.0),
            ),
            child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  ButtonTheme.bar(
                      child: ButtonBar(
                          children: <Widget>[
                            Text.rich(
                              TextSpan(text: '$_loca_ext'),
                            ),
                            FlatButton(
                              child: const Icon(Icons.map),
                              onPressed: () {
                                _getLocation();
                                var alt = _currentLocation["latitude"];
                                print("my $alt at location is: $_currentLocation");
                              },
                            )
                          ])
                  )
                ]),
          ),
        );
      }
    }
    

    With iOS, it gave the below error:

    error Permission denied

    Knowing that in the Info.plist, I added the below:

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

    NOTE

    It work if I granted it manually in the settings/privacy/location, but I need to do it programmatically, or guide the user to do it.

    • Scriptable
      Scriptable over 5 years
      If the user in iOS has rejected the permissions you need to redirect them to the settings menu for them to enable it.