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