126 lines
3.6 KiB
Dart
126 lines
3.6 KiB
Dart
import 'dart:async';
|
|||
|
|
|
||
|
|
/// GPS 定位服务
|
||
|
|
/// 提供获取当前位置、权限请求等功能
|
||
|
|
class LocationService {
|
||
|
|
static LocationService? _instance;
|
||
|
|
|
||
|
|
LocationService._internal();
|
||
|
|
|
||
|
|
factory LocationService() {
|
||
|
|
_instance ??= LocationService._internal();
|
||
|
|
return _instance!;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 请求位置权限
|
||
|
|
Future<bool> requestPermission() async {
|
||
|
|
// TODO: 使用 geolocator 请求权限
|
||
|
|
// final permission = await Geolocator.requestPermission();
|
||
|
|
// return permission == LocationPermission.always || permission == LocationPermission.whileInUse;
|
||
|
|
print('[LocationService] 请求位置权限(模拟)');
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 检查位置权限状态
|
||
|
|
Future<bool> hasPermission() async {
|
||
|
|
// TODO: 使用 geolocator 检查权限
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 检查 GPS 是否开启
|
||
|
|
Future<bool> isGpsEnabled() async {
|
||
|
|
// TODO: 使用 geolocator 检查 GPS 状态
|
||
|
|
// return await Geolocator.isLocationServiceEnabled();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 获取当前位置
|
||
|
|
Future<LocationData?> getCurrentLocation() async {
|
||
|
|
try {
|
||
|
|
final hasPermission = await requestPermission();
|
||
|
|
if (!hasPermission) return null;
|
||
|
|
|
||
|
|
// TODO: 使用 geolocator 获取位置
|
||
|
|
// final position = await Geolocator.getCurrentPosition(
|
||
|
|
// desiredAccuracy: LocationAccuracy.high,
|
||
|
|
// );
|
||
|
|
// return LocationData(
|
||
|
|
// latitude: position.latitude,
|
||
|
|
// longitude: position.longitude,
|
||
|
|
// accuracy: position.accuracy,
|
||
|
|
// );
|
||
|
|
|
||
|
|
// 模拟位置数据(杭州市中心)
|
||
|
|
return LocationData(
|
||
|
|
latitude: 30.2741,
|
||
|
|
longitude: 120.1551,
|
||
|
|
accuracy: 10.0,
|
||
|
|
altitude: 15.0,
|
||
|
|
timestamp: DateTime.now(),
|
||
|
|
);
|
||
|
|
} catch (e) {
|
||
|
|
print('[LocationService] 获取位置失败: $e');
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 持续监听位置变化
|
||
|
|
Stream<LocationData> watchLocation() async* {
|
||
|
|
// TODO: 使用 geolocator 的位置流
|
||
|
|
// final positionStream = Geolocator.getPositionStream(
|
||
|
|
// locationSettings: LocationSettings(accuracy: LocationAccuracy.high),
|
||
|
|
// );
|
||
|
|
// await for (final position in positionStream) {
|
||
|
|
// yield LocationData.fromPosition(position);
|
||
|
|
// }
|
||
|
|
|
||
|
|
// 模拟位置流
|
||
|
|
while (true) {
|
||
|
|
await Future.delayed(const Duration(seconds: 5));
|
||
|
|
yield LocationData(
|
||
|
|
latitude: 30.2741 + (DateTime.now().millisecondsSinceEpoch % 100) / 10000,
|
||
|
|
longitude: 120.1551 + (DateTime.now().millisecondsSinceEpoch % 100) / 10000,
|
||
|
|
accuracy: 10.0,
|
||
|
|
timestamp: DateTime.now(),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 计算两点之间的距离(米)
|
||
|
|
double distanceBetween(
|
||
|
|
double startLatitude,
|
||
|
|
double startLongitude,
|
||
|
|
double endLatitude,
|
||
|
|
double endLongitude,
|
||
|
|
) {
|
||
|
|
// TODO: 使用 geolocator 计算距离
|
||
|
|
// return Geolocator.distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude);
|
||
|
|
// 简单估算
|
||
|
|
const earthRadius = 6371000.0;
|
||
|
|
final dLat = (endLatitude - startLatitude) * 3.14159 / 180;
|
||
|
|
final dLon = (endLongitude - startLongitude) * 3.14159 / 180;
|
||
|
|
final a = dLat * dLat + dLon * dLon * 0.25;
|
||
|
|
return earthRadius * 2 * a * 1000;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 位置数据模型
|
||
|
|
class LocationData {
|
||
|
|
final double latitude;
|
||
|
|
final double longitude;
|
||
|
|
final double accuracy;
|
||
|
|
final double? altitude;
|
||
|
|
final DateTime timestamp;
|
||
|
|
|
||
|
|
LocationData({
|
||
|
|
required this.latitude,
|
||
|
|
required this.longitude,
|
||
|
|
required this.accuracy,
|
||
|
|
this.altitude,
|
||
|
|
required this.timestamp,
|
||
|
|
});
|
||
|
|
|
||
|
|
@override
|
||
|
|
String toString() => 'LocationData(lat: $latitude, lng: $longitude, accuracy: $accuracy)';
|
||
|
|
}
|