繁体   English   中英

将地理定位器 GPS stream 与 Riverpod StreamProvider 一起使用

[英]Using geolocator GPS stream with Riverpod StreamProvider

我正在努力使用地理定位器 package 的流式传输 GPS 功能 (StreamSubscription) 和 Riverpod 的 StreamProvider function,以便拥有一个不断更新用户 GPS 坐标的全局变量。 使用地理定位器 package 我能够获取并控制台记录用户的实时 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 中获得纬度/经度值,而不必使用全局经度和纬度。 我显然没有正确使用 Riverpod StreamProvider 并希望得到任何帮助。 谢谢。

这一行你立即终止套接字:

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

试试看:

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

创建一个提供者来保存 position 值

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 的值 stream

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM