我使用Geolocator
实现了一个渐进式Location
权限请求,因为我需要应用的后台位置,而Android
和iOS
平台都要求仅在获得while in use
权限后才能请求。问题是,虽然在Android
上,一切都按预期工作,第二次我用Prominent Disclosure
请求权限时,它打开了Location Permission
屏幕,iOS
上的未显示要求将权限更改为always allow
的第二个弹出窗口,仅返回LocationPermission.whileInUse
状态。已在运行iOS
12.5的iPhone6和运行iOS 16
的模拟器上尝试,但未显示第二个系统弹出窗口。我以为第二次请求权限时会看到第二个系统弹出窗口,我错了吗?
这是控制台上的指纹
// 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
这是用于请求权限的方法:
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;
});
}
我已经设置了Deployment target: 12.4
,在info.plist
中添加了两个条目
<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>
我还在Signing & Capabilities/Background Modes
中添加了Location updates
。
这是位置流方法,用于区分Android
和iOS
设置:
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;
}
现在,当我在iPhone6和iOS12.5上试用它时,我在系统弹出窗口中只看到Accept
和Deny
选项,但我还希望有Always allow
选项,所以我必须手动选择它,否则不会收到后台位置更新。难道不应该出现第二个系统弹出窗口以允许更改权限吗?
我错过了一些设置吗?非常感谢。
1条答案
按热度按时间fcg9iug31#
经过多次尝试(都失败了)打开第二个系统弹出窗口请求
always
权限,我开始想,正如Paulw11
所评论的,可能问题出在Geolocator
所做的通用位置权限请求上,所以我决定试试permission_handler
插件(只是为了iOS
启动)它确实允许检查状态和请求特定的位置权限类型。它确实起作用了。现在它最终打开第二系统弹出窗口以便用户可以将许可改变为总是,在iOS上(在模拟器和我即将退休的iPhone6上)以及Android平台上。这个通用位置权限实际上可能是iOS
不显示第二个系统弹出窗口的真正原因,即使使用permission_handler
也是如此Permission.location.request()
没有显示系统弹出窗口,而Permission.locationWhenInUse.request()
显示。下面是工作代码:位置
Bg位置