如何设置Geolocator.getPositionStream()的调用间隔以降低Google API成本
解决Geofire.setLocation调用频繁导致API费用过高的方案
第一步:优化Geolocator位置流的触发频率
默认的位置更新可能过于频繁,先通过配置distanceFilter(位置变化超过指定距离才触发)和intervalDuration(最小触发间隔)来减少回调次数:
updateDriversLocationAtRealTime() { streamSubscriptionPosition = Geolocator.getPositionStream( // 位置变化超过10米才触发更新 distanceFilter: 10, // 最少5秒触发一次更新 intervalDuration: const Duration(seconds: 5), ).listen((Position position) { driverCurrentPosition = position; // 地图实时更新保持正常,不影响体验 LatLng latLng = LatLng( driverCurrentPosition!.latitude, driverCurrentPosition!.longitude, ); newGoogleMapController!.animateCamera(CameraUpdate.newLatLng(latLng)); if(isDriverActive == true) { Geofire.setLocation( currentFirebaseUser!.uid, driverCurrentPosition!.latitude, driverCurrentPosition!.longitude ); } }); }
第二步:添加手动节流逻辑(双重保障)
如果上述配置仍无法满足费用控制需求,手动添加时间间隔判断,确保Geofire.setLocation仅在指定间隔内调用一次(比如10秒):
// 记录上次API调用的时间 DateTime? _lastApiCallTime; // 设置API调用的最小间隔(可根据需求调整) const _apiCallInterval = Duration(seconds: 10); updateDriversLocationAtRealTime() { streamSubscriptionPosition = Geolocator.getPositionStream( distanceFilter: 10, intervalDuration: const Duration(seconds: 5), ).listen((Position position) { driverCurrentPosition = position; // 地图实时更新不受节流影响 LatLng latLng = LatLng( driverCurrentPosition!.latitude, driverCurrentPosition!.longitude, ); newGoogleMapController!.animateCamera(CameraUpdate.newLatLng(latLng)); if(isDriverActive == true) { final now = DateTime.now(); // 判断是否已过设定的调用间隔 if(_lastApiCallTime == null || now.difference(_lastApiCallTime!) >= _apiCallInterval) { Geofire.setLocation( currentFirebaseUser!.uid, driverCurrentPosition!.latitude, driverCurrentPosition!.longitude ); _lastApiCallTime = now; } } }); }
额外优化:司机状态切换时的处理
当司机状态变为active时,立即更新一次位置;变为inactive时清空位置并重置计时,避免下次激活时延迟调用:
void toggleDriverActive(bool active) { isDriverActive = active; if(active) { // 激活时立即同步当前位置 if(driverCurrentPosition != null) { Geofire.setLocation( currentFirebaseUser!.uid, driverCurrentPosition!.latitude, driverCurrentPosition!.longitude ); _lastApiCallTime = DateTime.now(); } } else { // 非激活时移除位置记录(可选) Geofire.removeLocation(currentFirebaseUser!.uid); _lastApiCallTime = null; } }
内容的提问来源于stack exchange,提问作者Simone
相关产品推荐
相关产品推荐

