我有一个 flutter 应用程序,需要用户使用 permission_handler 包共享他们的位置,我检查他们的位置,如果未授予,我会显示一个信息对话框,通知用户我们需要他们的位置才能在应用程序上使用此特定功能。 一旦对话框关闭,我就会
openAppSettings()
然后我再次检查位置是否已授予,但是,它在真实设备上总是以禁用状态返回,在模拟器上按预期工作,这是我当前的代码:
Future<bool> _isLocationEnabled() async {
String? message;
final status = await Permission.location.status;
if (status.isDenied || status.isPermanentlyDenied) {
if (DeviceType.isAndroid || DeviceType.isIOS) {
message = 'Location_Disabled_Dialog.mobileMessage'.tr();
} else {
message = 'Location_Disabled_Dialog.webMessage'.tr();
}
await _dialogService.showCustomDialog<LocationDisabledDialogData, LocationDisabledDialogData>(
variant: DialogType.locationDisabled,
data: LocationDisabledDialogData(
message: message,
confirmed: false,
),
);
final didOpen = await openAppSettings();
return didOpen ? false : true; // Return false if settings were opened, true otherwise
}
if (status.isGranted) {
// If permission is granted, proceed
return true;
}
// If the status is anything else, request the permission
final result = await Permission.location.request();
return result.isGranted;
}
我尝试关闭应用程序,重新安装应用程序,但最终结果是相同的,始终表明用户尚未授予位置权限。
更新 这在 Android 上有效,在 iOS 上不起作用
您似乎在 iOS 上遇到了一个问题,即用户关闭应用程序设置后位置权限状态未正确更新。由于 iOS 如何处理权限更新,这是一个常见的挑战。
在 iOS 上,将用户重定向到应用设置后,当用户返回时应用可能不会立即收到通知,并且权限状态可能不会立即更新。以下是解决此问题的一些步骤和改进:
您似乎在 iOS 上遇到了一个问题,即用户关闭应用程序设置后位置权限状态未正确更新。由于 iOS 如何处理权限更新,这是一个常见的挑战。
在 iOS 上,将用户重定向到应用设置后,当用户返回时应用可能不会立即收到通知,并且权限状态可能不会立即更新。以下是解决此问题的一些步骤和改进:
AppLifecycleState
检测应用程序恢复不要在
openAppSettings()
之后立即检查权限,而是使用 WidgetsBindingObserver
来检测应用程序何时恢复。这样,当用户从设置返回时,您可以重新检查权限状态。
WidgetsBindingObserver
更新您的小部件以实现
WidgetsBindingObserver
:
class YourWidget extends StatefulWidget {
@override
_YourWidgetState createState() => _YourWidgetState();
}
class _YourWidgetState extends State<YourWidget> with WidgetsBindingObserver {
bool _locationGranted = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_checkLocationPermission();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// Check location permission when the app resumes
_checkLocationPermission();
}
}
Future<void> _checkLocationPermission() async {
bool granted = await _isLocationEnabled();
setState(() {
_locationGranted = granted;
});
if (!granted) {
// Handle the case where location is not granted
// Show dialog or prompt user again
}
}
Future<bool> _isLocationEnabled() async {
String? message;
final status = await Permission.location.status;
if (status.isDenied || status.isPermanentlyDenied) {
if (DeviceType.isAndroid || DeviceType.isIOS) {
message = 'Location_Disabled_Dialog.mobileMessage'.tr();
} else {
message = 'Location_Disabled_Dialog.webMessage'.tr();
}
await _dialogService.showCustomDialog<LocationDisabledDialogData, LocationDisabledDialogData>(
variant: DialogType.locationDisabled,
data: LocationDisabledDialogData(
message: message,
confirmed: false,
),
);
// Open app settings and wait for the user to return
await openAppSettings();
return false; // Return false until the user grants the permission
}
if (status.isGranted) {
return true; // Permission is granted
}
final result = await Permission.location.request();
return result.isGranted;
}
}
WidgetsBindingObserver
:该观察者允许您监听应用程序的生命周期变化。您可以检测应用程序何时恢复(带到前台),即您重新检查位置权限的时间。
didChangeAppLifecycleState
:当应用状态变为resumed
时,会重新检查位置权限状态。
确保
Info.plist
中的权限正确:仔细检查您的 Info.plist
是否包含正确的位置权限密钥:
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to provide certain features.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>We need your location to provide certain features even when the
app is in the background.</string>
Restart the Device
:有时,simulator
或device
可能需要重新启动permission changes
才能正常生效。
检查 iOS Version Specifics
:某些 iOS
版本可能会以不同方式处理权限,因此在多个版本上进行测试是有益的。