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