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()}');
 | ||
|     }
 | ||
|   }
 | ||
| }
 |