flutter - 将地理定位器 GPS 流与 Riverpod StreamProvider 结合使用

标签 flutter dart gps riverpod geolocator

我正在努力将地理定位器包的流式 GPS 功能 (StreamSubscription) 与 Riverpod 的 StreamProvider 功能结合使用,以便拥有一个不断更新用户 GPS 坐标的全局变量。使用 geolocator 包,我能够获取并控制台记录用户的实时 GPS 坐标,但我无法将这些流值获取到 Riverpod 变量中。我的代码如下。将不胜感激任何想法或提示。非常感谢。

https://riverpod.dev/docs/providers/stream_provider

https://pub.dev/documentation/geolocator/latest/

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:geolocator/geolocator.dart';
import 'dart:developer' as developer;

final userGpsProvider = StreamProvider<Position>((ref) {
  
  LocationSettings locationSettings = const LocationSettings(
    accuracy: LocationAccuracy.bestForNavigation,
    distanceFilter: 20, // in meters before an update is generated
  );

  Position? gpsPosition;

  final StreamSubscription<Position> socket =
      Geolocator.getPositionStream(locationSettings: locationSettings)
          .listen((Position? position) {
    developer.log('position ${position.toString()}');
    gpsPosition = position as Position;
  });

  ref.onDispose(socket?.cancel());

  developer.log('gpsPosition ${gpsPosition.toString()}');
  developer.log('socket ${socket.toString()}');

  return gpsPosition as Stream<Position>;
});

我修改了上面的代码,并更进一步,得到了一个工作版本。不幸的是,它涉及创建一些新的全局变量,这是我不想做的。

/// create global variables position, lng and lat 
/// (I don't want to do this, but it works)
late Position position;
String? lng = '';
String? lat = '';

final userGpsProvider = StreamProvider<Position>((ref) async* {
  LocationSettings locationSettings = const LocationSettings(
    accuracy: LocationAccuracy.bestForNavigation,
    distanceFilter: 20, // in meters before an update is generated
  );
  final StreamSubscription<Position> socket =
      Geolocator.getPositionStream(locationSettings: locationSettings)
          .listen((Position? position) {
    developer.log('position ${position.toString()}');
    lng = position?.longitude.toString();
    lat = position?.latitude.toString();
  });
  ref.onDispose(() => socket.cancel());
});

然后,在其他地方,我打电话:

final dynamic userGPS = ref.watch(userGpsProvider); 
developer.log('$userGPS.toString()');  // AsyncLoading<Position>()
developer.log('from main lng:  $lng');                 // -74.23
developer.log('from main lat:  $lat');                 // 54.23

全局 lng 和 lat 确实有正确的值,但我只在 userGPS 中获得 AsyncLoading。我希望通过 Riverpod 提供商 userGpsProvider 在 userGPS 中获得 lat/lng 值,并且不必使用全局 lng 和 lat。我显然没有得到 Riverpod StreamProvider 的正确信息,并且希望得到任何帮助。谢谢。

最佳答案

创建一个提供者来持有头寸值(value)

final locationProvider = StateProvider<Position>((ref){
  return Position(longitude: 0.0, latitude: 0.0, timestamp: DateTime.now(), accuracy: 0, altitude: 0, heading: 0, speed: 0,      speedAccuracy: 0);
});

更新 Geolocator.getPositionStream 流中 locationProvider 的值

final locationStateProvider = StreamProvider.autoDispose<Position>((ref){
  LocationSettings locationSettings = const LocationSettings(accuracy: LocationAccuracy.medium, distanceFilter: 20);
  return Geolocator.getPositionStream(locationSettings: locationSettings).map((position){
    ref.read(locationProvider.notifier).state = position;
    return position;
  });
});

在父树中的任何位置监视(初始化)locationStateProvider。无需将其分配给任何东西

ref.watch(locationStateProvider);

监视位置提供商

final location = ref.watch(locationProvider);

关于flutter - 将地理定位器 GPS 流与 Riverpod StreamProvider 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74932450/

相关文章:

dart - Flutter 隔离与 future

dart - Paypal 订单 v2 : the approveurl of the order ("checkoutnow?token..") returns 302 redirect

flutter - PS256 在 Flutter/Dart 中签名

android - 在 android studio 中如何从磁盘重新加载代码文件?

android - 为什么当我使用 pushNamedReplacement 而不是 pushReplacement 时它不起作用?

firebase - 如何在 Flutter 中从 Firestore 订购数据,orderBy 订购不正确

flutter - Getx Flutter - 更新列表中的项目不是 react 性的

android - 我如何在 Android 上获取 GPS 定位状态 - 现在(不使用监听器)

android - 如何知道卫星已经在 android 上找到或正在搜索?

windows-phone-7 - Windows Phone 8 平台上的 GPS 错误行为