未能显示第二个弹出窗口要求始终允许 iOS Flutter 上的位置权限

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

我已经使用

Location
实现了一个渐进式
Geolocator
权限请求,因为我需要我的应用程序的后台位置,并且
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>

我还在

Location updates
中添加了
Signing & Capabilities/Background Modes

这是位置流方法,区分

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;
  }

现在,当我在装有 iOS 12.5 的 iPhone 6 上试用它时,我在系统弹出窗口中只看到

Accept
Deny
选项,但我还期望有一个
Always allow
选项,所以我必须手动选择它否则未收到背景位置更新。 不应该出现第二个系统弹出窗口以允许更改权限吗?

我错过了一些设置吗? 非常感谢。

ios flutter background location flutter-dependencies
1个回答
0
投票

在多次尝试(全部失败)以打开第二个系统弹出窗口以请求

always
权限后,我开始认为正如
Paulw11
所评论的那样,问题可能出在
Geolocator
所做的通用位置权限请求,所以我决定尝试
permission_handler
插件(只是为了
iOS
开始)它允许检查状态并请求特定的位置权限类型。它确实有效..它现在终于打开了第二个系统弹出窗口,因此用户可以在 iOS(在模拟器和我即将退休的 iPhone6 上)以及 Android 平台上将权限更改为始终。一般位置许可实际上可能是
iOS
没有显示第二个系统弹出窗口的真正原因,即使我使用
permission_handler
也没有显示第二个系统弹出窗口,而
Permission.location.request()
显示。 这是工作代码:
地点

Permission.locationWhenInUse.request()

Bg位置

/// Using permission_handler for both platforms Future<String> getLocationPermission() async { print('\n\nLocationRepository.getLocationPermission() started\n\n'); late String permission; permission = await Permission.locationWhenInUse.status.then((value) { print( '\n\n LocationRepository.getLocationPermission Permission.locationWhenInUse.status is ${value.name}'); // permission = await Permission.location.status.then((value) { // print( // '\n\n LocationRepository.getLocationPermission Permission.location.status is ${value.name}'); switch (value) { case PermissionStatus.denied: return 'denied'; case PermissionStatus.permanentlyDenied: return 'deniedForever'; case PermissionStatus.limited: return 'limited'; case PermissionStatus.granted: return 'granted'; case PermissionStatus.restricted: return 'restricted'; } }); return permission; } Future<String> requestLocationPermission() async { print('LocationRepository.requestLocationPermission started'); late String permission; // general location doesn't open the popup // var status = await Permission.location.status; // print('Permission.location.status is $status'); var status = await Permission.locationWhenInUse.status; print('Permission.locationWhenInUse.status is $status'); /// NOT Granted if (!status.isGranted) { // var status = await Permission.location.request(); // print('Permission.location.request() status is $status'); var status = await Permission.locationWhenInUse.request(); print('Permission.locationWhenInUse.request() status is $status'); if (status.isGranted) { permission = 'granted'; } else { permission = 'denied'; } } /// Granted else { permission = 'granted'; } return permission; }

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