[英]Flutter Riverpod : return 2 stream with 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.