flutter_location_wakeup

flutter_location_wakeup 是一个 Flutter 插件,旨在监听设备上的显著位置变化。当检测到变化时,前台应用会被唤醒,或在暂停状态下保持唤醒。当您需要位置变化来保持前台应用运行时,例如在导航应用或基于位置交互的应用中,可以使用此库。

该插件的 iOS 实现主要依赖于 Apple 的 startMonitoringSignificantLocationChanges Swift API。有关其功能的深入了解,请参阅 Apple 的官方文档。目前,该插件仅支持 iOS,Android 支持正在开发中。

入门

iOS 配置

要为 iOS 设置该插件,您需要请求位置权限。将以下键添加到 Info.plist 文件中,以说明使用位置的原因。

	<key>NSLocationWhenInUseUsageDescription</key>
	<string>We need your location for...</string>
	<key>NSLocationAlwaysUsageDescription</key>
	<string>We need your location for...</string>
	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
	<string>We need your location for...</string>

示例用法

有关全面的演示,请参阅 example 目录中提供的示例。

Sample Usage

使用 iOS Simulator 的 Freeway Drive 功能测试该功能。

Freeway Drive

以下代码片段展示了一个响应位置更新并在 SnackBar 中显示它们的有状态小部件。

class _LocationDisplayState extends State<LocationDisplay> {
  String _display = 'Unknown';
  final _locationWakeup = LocationWakeup();

  @override
  void initState() {
    super.initState();
    startListening();
  }

  Future<void> startListening() async {
    if (!mounted) return;

    try {
      //Start listening before initializing
      _locationWakeup.locationUpdates.listen(
        (result) {
          if (!mounted) return;

          setState(() => onLocationResultChange(result));
        },
      );
      //Initialize
      await _locationWakeup.startMonitoring();
    } on PlatformException {
      // Handle exception
    }
  }

  void onLocationResultChange(LocationResult result) {
    _display = result.match(
        onSuccess: (l) => '''
Lat: ${l.latitude}
Long: ${l.longitude}
Altitude: ${l.altitude}
Horizontal Accuracy: ${l.horizontalAccuracy}
Vertical Accuracy: ${l.verticalAccuracy}
Course: ${l.course}
Speed: ${l.speed}
Timestamp: ${l.timestamp}
Floor Level: ${l.floorLevel}
''',
        onError: (e) => e.message);

    messengerStateKey.currentState.let(
      (state) async => state.showSnackBar(
        SnackBar(
          content: Text(
            _display,
            style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
          ),
          backgroundColor: Theme.of(state.context).colorScheme.background,
          behavior: SnackBarBehavior.floating,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
          margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
          duration: const Duration(seconds: 10),
          action: SnackBarAction(
            label: 'Dismiss',
            onPressed: () {},
            textColor: Colors.white,
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) => Text(_display);
}

GitHub

查看 Github