94 lines
2.5 KiB
Dart
94 lines
2.5 KiB
Dart
import 'dart:async';
|
||
import 'dart:io';
|
||
|
||
import 'package:amap_flutter_location/amap_flutter_location.dart';
|
||
import 'package:amap_flutter_location/amap_location_option.dart';
|
||
import 'package:autosos_flutter/config/constant.dart';
|
||
import 'package:flutter/foundation.dart';
|
||
|
||
/// 定位服务(封装 AMap Flutter Location 3.0)
|
||
class LocationService {
|
||
static final LocationService instance = LocationService._();
|
||
LocationService._();
|
||
|
||
final _location = AMapFlutterLocation();
|
||
final _positionController =
|
||
StreamController<Map<String, Object>>.broadcast();
|
||
|
||
Stream<Map<String, Object>> get positionStream => _positionController.stream;
|
||
|
||
Map<String, Object>? _last;
|
||
Map<String, Object>? get last => _last;
|
||
|
||
bool _initialized = false;
|
||
|
||
/// 初始化并请求权限
|
||
Future<bool> init({
|
||
String androidKey = '',
|
||
String iosKey = '',
|
||
}) async {
|
||
try {
|
||
if (_initialized) return true;
|
||
AMapFlutterLocation.setApiKey(androidKey, iosKey);
|
||
|
||
_location.setLocationOption(AMapLocationOption(
|
||
locationMode: AMapLocationMode.Hight_Accuracy,
|
||
onceLocation: false,
|
||
locationInterval: 5000, // 5 秒
|
||
desiredAccuracy: DesiredAccuracy.Best,
|
||
distanceFilter: -1,
|
||
needAddress: true,
|
||
));
|
||
|
||
_location.onLocationChanged().listen((event) {
|
||
_last = event;
|
||
Constant.lat = (event['latitude'] as num?)?.toDouble() ?? 0;
|
||
Constant.lng = (event['longitude'] as num?)?.toDouble() ?? 0;
|
||
Constant.address = (event['address'] as String?) ?? '';
|
||
_positionController.add(event);
|
||
});
|
||
|
||
_initialized = true;
|
||
return true;
|
||
} catch (e) {
|
||
debugPrint('LocationService init failed: $e');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// 开始定位
|
||
void start() {
|
||
_location.startLocation();
|
||
}
|
||
|
||
/// 停止定位
|
||
void stop() {
|
||
_location.stopLocation();
|
||
}
|
||
|
||
/// 单次定位(用于初始定位、报点等)
|
||
Future<Map<String, Object>?> fetchOnce() async {
|
||
start();
|
||
final completer = Completer<Map<String, Object>?>();
|
||
final sub = positionStream.listen((loc) {
|
||
if (!completer.isCompleted) completer.complete(loc);
|
||
});
|
||
final loc = await completer.future.timeout(
|
||
const Duration(seconds: 10),
|
||
onTimeout: () => null,
|
||
);
|
||
await sub.cancel();
|
||
return loc;
|
||
}
|
||
|
||
void dispose() {
|
||
_location.stopLocation();
|
||
_location.destroy();
|
||
_positionController.close();
|
||
}
|
||
|
||
/// 平台判断辅助
|
||
static bool get isAndroid => Platform.isAndroid;
|
||
static bool get isIOS => Platform.isIOS;
|
||
}
|