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

fquxozlt  于 2022-12-30  发布在  Flutter
关注(0)|答案(1)|浏览(309)

我在纠结如何使用流媒体GPS功能(StreamSubscription)的地理定位器包与StreamProvider功能的Riverpod,以便有一个全局变量,不断更新用户的GPS坐标。使用地理定位器包,我能够获得和控制台日志用户的实时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>;
});

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

/// 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,并将感谢任何帮助。谢谢。

w80xi6nr

w80xi6nr1#

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

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

试试看:

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

相关问题