해결된 질문
작성
·
295
0
버튼 클릭시 trackingOff()를 호출해서 중지시킬려고 해도 StreamProvider가 중지가 되지않아서 그러는데 StreamProvider는 중지 시킬 수 없나여?
class LocationUtil {
late UserLocation userLocation;
late Position _currentPosition;
late LocationPermission checkPermission;
StreamSubscription<Position>? positionStream;
Geolocator geolocator = Geolocator();
StreamController<UserLocation> _positionController =
StreamController<UserLocation>();
Stream<UserLocation> get locationStream => _positionController.stream;
final LocationSettings locationSettings =
LocationSettings(accuracy: LocationAccuracy.high);
// 추적 버튼 클릭시에만 현재 위치 주기적으로 업데이트
LocationUtil() {
// 사용자의 현재 위치 계속 업데이트해주기
positionStream =
Geolocator.getPositionStream(locationSettings: locationSettings)
.listen((location) {
_positionController
.add(UserLocation(location.latitude, location.longitude));
});
}
Future<UserLocation> getCurrentLocation() async {
try {
final isLocationEnabled = await Geolocator.isLocationServiceEnabled();
checkPermission = await Geolocator.checkPermission();
log("${isLocationEnabled} isLocationEnabled 확인");
// 권한이 없을때
if (!isLocationEnabled) {
log("${checkPermission} checkPermission 확인");
// 권한 설정 확인
if (checkPermission == LocationPermission.denied ||
checkPermission == LocationPermission.deniedForever) {
checkPermission = await Geolocator.requestPermission();
}
// 한번더 권한 취소햇으면
if (checkPermission == LocationPermission.denied ||
checkPermission == LocationPermission.deniedForever) {
throw Exception("denied'");
}
} else if (isLocationEnabled &&
(checkPermission == LocationPermission.always ||
checkPermission == LocationPermission.whileInUse)) {
_currentPosition = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
userLocation =
UserLocation(_currentPosition.latitude, _currentPosition.longitude);
}
} catch (e) {
log("${e} 경복궁 보여줍시다.");
userLocation = UserLocation(37.579887, 126.976870);
}
log("${userLocation.latitude},${userLocation.longitude} 현재 위치 위도 경도");
return userLocation;
}
void closePosition() {
if (positionStream != null) {
log("종료입니다");
positionStream!.cancel();
_positionController.close();
positionStream = null;
} else {}
}
void trackingOn(){
positionStream!.resume();
_positionController.onResume;
}
void trackingOff(){
log("off입니다.");
positionStream!.pause();
_positionController.onPause;
log("${positionStream!.isPaused}");
}
}
StreamProvider<UserLocation>(
initialData: Provider.of<LocationNotifier>(context).userLocation,
create: (context) => LocationUtil().locationStream,
child: Consumer<LocationNotifier>(
builder: (context, locationNotifier, _) {
CameraPosition initialCameraPosition = CameraPosition(
target: LatLng(Provider.of<UserLocation>(context).latitude,
Provider.of<UserLocation>(context).longitude),
zoom: 18);
log("반복하는지 테스트입니다!!!!");
animatedViewofMap(
lat: Provider.of<UserLocation>(context).latitude,
lng: Provider.of<UserLocation>(context).longitude,
zoom: null);
return Stack(children: [
GoogleMap(
initialCameraPosition: initialCameraPosition,
myLocationEnabled: true,
mapToolbarEnabled: true,
myLocationButtonEnabled: true,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
markers: markerList,
),
]);
}),
)
답변 1
0
안녕하세요 정충효 님, 인프런 AI 인턴이에요.
위에 작성해주신 코드를 보면 LocationUtil
클래스 안에 UserProfile
이라는 데이터를 스트림으로 제공하는 StreamProvider
가 포함되어 있습니다. StreamProvider
를 중지시키려는 trackingOff()
메소드를 통해 스트림을 일시적으로 멈추고 싶으신 것으로 이해하겠습니다.
하지만 StreamProvider
의 스트림을 직접 중지시키는 기능은 제공되지 않습니다. StreamProvider
는 스트림을 생성하고 구독자들에게 해당 스트림을 제공하는 역할을 합니다. 스트림을 멈추거나 다시 시작하는 것은 StreamProvider
가 아닌 스트림 자체를 제어해야 합니다.
따라서 trackingOff()
메소드에서 스트림을 일시적으로 중지시키려면 positionStream
변수에 대한 제어를 해주어야 합니다. 현재 positionStream
은 Geolocator.getPositionStream()
메소드로 생성된 스트림에 대한 구독(subscription)을 참조하고 있습니다.
trackingOff()
메소드 안에서 positionStream
을 멈추기 위해 positionStream!.pause()
를 호출하셨는데, 이 부분에서 오류가 발생할 수 있습니다. 스트림을 일시적으로 멈추는 게 아니라 positionStream
구독 참조자체를 제거하고 싶다면 positionStream!.cancel()
을 호출해야 합니다.
따라서 trackingOff()
메소드를 다음과 같이 수정하시면 됩니다:
void trackingOff() {
log("off입니다.");
positionStream?.cancel();
_positionController.onPause;
log("${positionStream?.isPaused}");
}
위의 수정사항을 적용한 뒤 trackingOff()
메소드를 호출하면 positionStream
의 구독이 취소되고 스트림이 중지됩니다.
그러나 유의할 점은 StreamProvider
는 Stream<UserLocation>
을 제공하는 역할을 하므로, 스트림을 중지시키면 StreamProvider
가 새로운 데이터를 제공하지 않게 됩니다. 따라서 스트림을 중지시킬 경우, StreamProvider
를 사용하는 구성요소에서 StreamBuilder
등으로 해당 스트림이 중지됨을 처리해주어야 합니다.
이점을 유의하시고 위의 수정사항을 참고하여 코드를 작성해보시기 바랍니다. 감사합니다!