import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:geolocator/geolocator.dart'; import 'package:permission_handler/permission_handler.dart'; /// 위치 권한 상태 Provider final locationPermissionProvider = FutureProvider(( ref, ) async { return await Permission.location.status; }); /// 현재 위치 Provider final currentLocationProvider = FutureProvider((ref) async { // 위치 권한 확인 final permissionStatus = await Permission.location.status; if (!permissionStatus.isGranted) { // 권한이 없으면 요청 final result = await Permission.location.request(); if (!result.isGranted) { return null; } } // 위치 서비스 활성화 확인 final serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { throw Exception('위치 서비스가 비활성화되어 있습니다'); } // 현재 위치 가져오기 try { return await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, timeLimit: const Duration(seconds: 10), ); } catch (e) { // 타임아웃이나 오류 발생 시 마지막 알려진 위치 반환 return await Geolocator.getLastKnownPosition(); } }); /// 위치 스트림 Provider final locationStreamProvider = StreamProvider((ref) { return Geolocator.getPositionStream( locationSettings: const LocationSettings( accuracy: LocationAccuracy.high, distanceFilter: 10, // 10미터 이상 이동 시 업데이트 ), ); }); /// 위치 관리 StateNotifier class LocationNotifier extends StateNotifier> { LocationNotifier() : super(const AsyncValue.loading()); /// 위치 권한 요청 Future requestLocationPermission() async { try { final status = await Permission.location.request(); return status.isGranted; } catch (e) { return false; } } /// 위치 서비스 활성화 요청 Future requestLocationService() async { try { return await Geolocator.openLocationSettings(); } catch (e) { return false; } } /// 현재 위치 가져오기 Future getCurrentLocation() async { state = const AsyncValue.loading(); try { // 권한 확인 final permissionStatus = await Permission.location.status; if (!permissionStatus.isGranted) { final granted = await requestLocationPermission(); if (!granted) { state = const AsyncValue.data(null); return; } } // 위치 서비스 확인 final serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { state = AsyncValue.error('위치 서비스가 비활성화되어 있습니다', StackTrace.current); return; } // 위치 가져오기 final position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, timeLimit: const Duration(seconds: 10), ); state = AsyncValue.data(position); } catch (e, stack) { // 오류 발생 시 마지막 알려진 위치 시도 try { final lastPosition = await Geolocator.getLastKnownPosition(); state = AsyncValue.data(lastPosition); } catch (_) { state = AsyncValue.error(e, stack); } } } /// 두 지점 간의 거리 계산 (미터 단위) double calculateDistance( double startLatitude, double startLongitude, double endLatitude, double endLongitude, ) { return Geolocator.distanceBetween( startLatitude, startLongitude, endLatitude, endLongitude, ); } } /// LocationNotifier Provider final locationNotifierProvider = StateNotifierProvider>((ref) { return LocationNotifier(); });