| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- //
- // MapAmapGetLocationHandle.swift
- // map_amap_ios
- //
- // Created by 诺诺诺的言 on 2025/7/22.
- //
- import Foundation
- import Flutter
- import CoreLocation
- @available(iOS 13.0, *)
- class LocationManager: NSObject {
- static let shared = LocationManager()
- private var locationUpdateEventChannel: FlutterEventChannel?
- private var locationEventSink: FlutterEventSink?
- private let locationManager = CLLocationManager()
- #if DEBUG
- private let filterDistance: CLLocationDistance = 5
- #else
- private let filterDistance: CLLocationDistance = 20
- #endif
- private var lastLocation: CLLocation?
- private var lastUpdateTime: Date?
- var onLocationUpdate: ((CLLocation) -> Void)?
- private override init() {
- super.init()
- locationManager.delegate = self
- setup()
- }
-
- func initChannel(withMessenger messenger: FlutterBinaryMessenger) {
- locationUpdateEventChannel = FlutterEventChannel(name: MapAmapViewOnlyKeyword.locationUpdateEventChannelName, binaryMessenger: messenger)
- locationUpdateEventChannel?.setStreamHandler(self)
- }
- func start(withMessenger messenger: FlutterBinaryMessenger) -> Bool {
- // permission detect
- switch CLLocationManager.authorizationStatus() {
- case .authorizedWhenInUse, .authorizedAlways:
- locationManager.startUpdatingLocation()
- //setupMessenger(messenger: messenger)
- return true
- case .notDetermined:
- return false
- default:
- print("LocationManager: authorizationStatus: \(CLLocationManager.authorizationStatus())")
- return false
- }
- }
- func stop() {
- locationManager.stopUpdatingLocation()
- }
- // func setupMessenger(messenger: FlutterBinaryMessenger) {
- // guard locationUpdateEventChannel == nil && locationEventSink == nil else { return }
- // locationUpdateEventChannel = FlutterEventChannel(name: MapKitConstans.locationUpdateEventChannelName, binaryMessenger: messenger)
- // locationUpdateEventChannel?.setStreamHandler(self)
- // }
- func setup() {
- locationManager.allowsBackgroundLocationUpdates = true
- locationManager.pausesLocationUpdatesAutomatically = false
- locationManager.desiredAccuracy = kCLLocationAccuracyBest
- // locationManager.distanceFilter = filterDistance
- locationManager.activityType = .automotiveNavigation
- locationManager.showsBackgroundLocationIndicator = false
- }
- @available(iOS 13.0.0, *)
- static func getAddress(location: CLLocation) async -> String? {
- let geocoder = CLGeocoder()
- return await withCheckedContinuation { continuation in
- geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
- if let error = error {
- print("反向地理编码失败: \(error.localizedDescription)")
- continuation.resume(returning: nil)
- return
- }
-
- if let placemark = placemarks?.first {
- // 获取完整地址
- let address = [
- placemark.country,
- placemark.administrativeArea,
- placemark.locality,
- placemark.subLocality,
- placemark.thoroughfare,
- placemark.subThoroughfare,
- placemark.name
- ].compactMap { $0 }.joined(separator: "")
-
- continuation.resume(returning: address)
- } else {
- continuation.resume(returning: nil)
- }
- }
- }
- }
- }
- @available(iOS 13.0, *)
- extension LocationManager: CLLocationManagerDelegate {
- func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
- guard let location = locations.last, isLocationCanUpdate(location: location) else { return }
- onLocationUpdate?(location)
- if let eventSink = locationEventSink {
- Task {
- // 转换GPS坐标系到中国坐标系
- let transformedCoordinate = location.coordinate.wgc84ToGCJ02
- let atLocation = ATMapLocation.fromLocation(location: location)
- atLocation.longitude = transformedCoordinate.longitude
- atLocation.latitude = transformedCoordinate.latitude
- // 获取地址
- atLocation.address = await LocationManager.getAddress(location: location)
-
- let jsonMessage = atLocation.toJson()
- print(jsonMessage)
- await MainActor.run {
- eventSink(jsonMessage)
- }
- }
-
- }
- }
- func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
- print("LocationManager: didFailWithError: \(error)")
- }
- func isLocationCanUpdate(location: CLLocation) -> Bool {
- if let lastLocation = lastLocation {
- let distance = location.distance(from: lastLocation)
- let timeInterval = location.timestamp.timeIntervalSince(lastUpdateTime ?? Date())
- if timeInterval < 5.0 {
- return false
- }
- }
- lastLocation = location
- lastUpdateTime = location.timestamp
- return true
- }
- }
- @available(iOS 13.0, *)
- extension LocationManager: FlutterStreamHandler {
- func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
- locationEventSink = events
- return nil
- }
- func onCancel(withArguments arguments: Any?) -> FlutterError? {
- locationEventSink = nil
- return nil
- }
- }
|