72 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Dart
		
	
	
		
		
			
		
	
	
			72 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Dart
		
	
	
|  | import 'package:geolocator/geolocator.dart'; | |||
|  | 
 | |||
|  | class LocationResult { | |||
|  |   final String latitude; | |||
|  |   final String longitude; | |||
|  | 
 | |||
|  |   LocationResult({ | |||
|  |     required this.latitude, | |||
|  |     required this.longitude, | |||
|  |   }); | |||
|  | 
 | |||
|  |   factory LocationResult.fromPosition(Position p) { | |||
|  |     return LocationResult( | |||
|  |       latitude: p.latitude.toString(), | |||
|  |       longitude: p.longitude.toString(), | |||
|  |     ); | |||
|  |   } | |||
|  | 
 | |||
|  |   double? get latitudeAsDouble => double.tryParse(latitude); | |||
|  |   double? get longitudeAsDouble => double.tryParse(longitude); | |||
|  | 
 | |||
|  |   @override | |||
|  |   String toString() => 'LocationResult(latitude: $latitude, longitude: $longitude)'; | |||
|  | } | |||
|  | 
 | |||
|  | class LocationException implements Exception { | |||
|  |   final String message; | |||
|  |   LocationException(this.message); | |||
|  |   @override | |||
|  |   String toString() => message; | |||
|  | } | |||
|  | 
 | |||
|  | /// 统一处理定位权限与获取经纬度(字符串形式)
 | |||
|  | class LocationService { | |||
|  |   /// 获取当前经纬度(字符串形式),成功返回 LocationResult,失败抛出 LocationException
 | |||
|  |   static Future<LocationResult> getCurrentLocation({ | |||
|  |     Duration timeout = const Duration(seconds: 10), | |||
|  |   }) async { | |||
|  |     // 检查定位服务是否开启
 | |||
|  |     bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); | |||
|  |     if (!serviceEnabled) { | |||
|  |       await Geolocator.openLocationSettings(); | |||
|  |       throw LocationException('定位服务未开启,请打开设备定位后重试'); | |||
|  |     } | |||
|  | 
 | |||
|  |     // 检查/请求权限
 | |||
|  |     LocationPermission permission = await Geolocator.checkPermission(); | |||
|  |     if (permission == LocationPermission.denied) { | |||
|  |       permission = await Geolocator.requestPermission(); | |||
|  |       if (permission == LocationPermission.denied) { | |||
|  |         throw LocationException('定位权限被拒绝'); | |||
|  |       } | |||
|  |     } | |||
|  | 
 | |||
|  |     if (permission == LocationPermission.deniedForever) { | |||
|  |       throw LocationException( | |||
|  |         '定位权限被永久拒绝,请去系统设置中为应用打开定位权限', | |||
|  |       ); | |||
|  |     } | |||
|  | 
 | |||
|  |     // 获取位置(带超时)
 | |||
|  |     try { | |||
|  |       final position = await Geolocator | |||
|  |           .getCurrentPosition(desiredAccuracy: LocationAccuracy.high) | |||
|  |           .timeout(timeout); | |||
|  |       return LocationResult.fromPosition(position); | |||
|  |     } on Exception catch (e) { | |||
|  |       throw LocationException('获取位置失败: ${e.toString()}'); | |||
|  |     } | |||
|  |   } | |||
|  | } |