I've implemented a progressive Location
permission request using Geolocator
as I need background location for my app and both Android
and iOS
platforms require it to be asked only after being granted the while in use
permission. The problem is that while on Android
it all works as expected and the second time I request permission with a Prominent Disclosure
it opens the Location Permission
screen, on iOS
is not showing a second pop-up asking to change the permission to always allow
and just returns the LocationPermission.whileInUse
status.
Tried both on iPhone6 running iOS
12.5 and Simulator running iOS 16
but the second system popup doesn't appear.
I'm I wrong expecting to see a second system popup when requesting permission a second time?
Here are the prints from the console:
// at start
flutter: LocationBloc.getLocationPermission value is denied
// at first request system popup appears
flutter: LocationBloc._requestLocationPermission value is whileInUse
// at second request system popup doesn't appear
flutter: TrackingRepository.getLocationPermission() LocationPermission is: LocationPermission.whileInUse
flutter: TrackingBloc._getBackgroundLocationPermission value is whileInUse
flutter: TrackingRepository.requestLocationPermission() LocationPermission is: LocationPermission.whileInUse
flutter: TrackingBloc._requestLocationPermission value is whileInUse
This is the method used to request permission:
Future<String> requestLocationPermission() async {
return await locationManager.checkPermission().then((value) async {
late String permission;
if (value != LocationPermission.always) {
permission =
await locationManager.requestPermission().then((value) async {
print(
'TrackingRepository.requestLocationPermission() LocationPermission is: $value');
switch (value) {
case LocationPermission.denied:
return 'denied';
case LocationPermission.deniedForever:
return 'deniedForever';
case LocationPermission.whileInUse:
return 'whileInUse';
case LocationPermission.always:
return 'always';
case LocationPermission.unableToDetermine:
return 'unableToDetermine';
}
}).catchError((e) {
print('TrackingRepository.requestLocationPermission() error: $e');
});
}
return permission;
});
}
I have set Deployment target: 12.4
, added two entries in info.plist
as
<key>NSLocationWhenInUseUsageDescription</key>
<string>fixit needs you position to enable its functionalities</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>fixit needs your position to enable you to track your routes even when is in background</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>fixit needs your position to enable you to track your routes even when is in background</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>location</string>
<string>processing</string>
<string>remote-notification</string>
</array>
I also added the Location updates
in Signing & Capabilities/Background Modes
.
This is the location stream method, which differentiate between Android
and iOS
settings:
Stream<Position> startTracking() {
_positionStreamController = new StreamController<Position>.broadcast();
locationManager.checkPermission().then((value) async {
if (value == LocationPermission.denied ||
value == LocationPermission.deniedForever ||
value == LocationPermission.whileInUse) {
await locationManager.requestPermission().then((value) {
print(
'TrackingRepository.startTracking() requestPermission is: $value');
}).catchError((e) {
print(
'TrackingRepository.startTracking() requestPermission error: $e');
});
}
}).catchError((e) {
print('TrackingRepository.startTracking() error: $e');
});
late var locationSettings = Platform.isIOS
? AppleSettings(
accuracy: LocationAccuracy.bestForNavigation,
allowBackgroundLocationUpdates: true,
showBackgroundLocationIndicator: true,
activityType: ActivityType.otherNavigation)
: LocationSettings(accuracy: LocationAccuracy.best, distanceFilter: 0);
_positionSubscription = locationManager
.getPositionStream(locationSettings: locationSettings)
.listen((event) {
_positionStreamController.sink.add(event);
});
return _positionStreamController.stream;
}
Now, as I'm trying it on an iPhone 6 with iOS 12.5 I only see Accept
and Deny
options at system popup, but I was expecting also an Always allow
option, so I have to manually choose it otherwise background position updates are not received.
Isn't supposed to appear a second system popup to allow changing the permissions?
Am I missing out some settings? Many thanks.