模拟器与真机位置权限不一致

问题描述 投票:0回答:1

我有一个 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 上不起作用

flutter location
1个回答
0
投票

您似乎在 iOS 上遇到了一个问题,即用户关闭应用程序设置后位置权限状态未正确更新。由于 iOS 如何处理权限更新,这是一个常见的挑战。

在 iOS 上,将用户重定向到应用设置后,当用户返回时应用可能不会立即收到通知,并且权限状态可能不会立即更新。以下是解决此问题的一些步骤和改进:

您似乎在 iOS 上遇到了一个问题,即用户关闭应用程序设置后位置权限状态未正确更新。由于 iOS 如何处理权限更新,这是一个常见的挑战。

在 iOS 上,将用户重定向到应用设置后,当用户返回时应用可能不会立即收到通知,并且权限状态可能不会立即更新。以下是解决此问题的一些步骤和改进:

1.使用
AppLifecycleState
检测应用程序恢复

不要在

openAppSettings()
之后立即检查权限,而是使用
WidgetsBindingObserver
来检测应用程序何时恢复。这样,当用户从设置返回时,您可以重新检查权限状态。

2.使用
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;
  }
}

3.变更说明

WidgetsBindingObserver
:该观察者允许您监听应用程序的生命周期变化。您可以检测应用程序何时恢复(带到前台),即您重新检查位置权限的时间。
didChangeAppLifecycleState
:当应用状态变为
resumed
时,会重新检查位置权限状态。

4. iOS 注释

确保

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>

5.故障排除技巧

Restart the Device
:有时,
simulator
device
可能需要重新启动
permission changes
才能正常生效。 检查
iOS Version Specifics
:某些
iOS
版本可能会以不同方式处理权限,因此在多个版本上进行测试是有益的。

© www.soinside.com 2019 - 2024. All rights reserved.