123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- //
- // AmapLocationFactory.swift
- // amap_location
- //
- // Created by QiuLiang Wang on 2020/6/5.
- //
- import Foundation
- import AMapFoundationKit
- import AMapLocationKit
- class AmapLocationFactory: NSObject, AMapLocationManagerDelegate, FlutterStreamHandler {
- private var messenger: FlutterBinaryMessenger
- private var locationManager: AMapLocationManager
- private var eventSink: FlutterEventSink?
- private var timer: Timer?
- private var interval: Int = 2000
- private var start: Bool = true
- private var mapLoca: Dictionary<String, Any>?
- private var fetchLoca: Dictionary<String, Any>?
- private var fetchSink: FlutterResult?
-
- init(withMessenger messenger: FlutterBinaryMessenger) {
- self.messenger = messenger
- locationManager = AMapLocationManager()
- super.init()
-
- locationManager.distanceFilter = 5
- locationManager.delegate = self
- locationManager.locatingWithReGeocode = false
- locationManager.allowsBackgroundLocationUpdates = true
- }
-
- func register() {
- let channel = FlutterMethodChannel(name: "plugins.ouj.com/amap_location", binaryMessenger:messenger)
- channel.setMethodCallHandler(onMethodCall)
-
- let event = FlutterEventChannel(name: "plugins.ouj.com/amap_location_event", binaryMessenger: messenger)
- event.setStreamHandler(self)
- }
- func onMethodCall(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
- switch methodCall.method {
- case "fetch":
- let args = methodCall.arguments as? [String: Any]
- var accuracy = args?["accuracy"] as? Int
- if (accuracy == nil) {
- accuracy = 0
- }
- // 定位精度
- switch accuracy {
- case 1:
- locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
- case 2:
- locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
- case 3:
- locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
- case 4:
- locationManager.desiredAccuracy = kCLLocationAccuracyBest
- default:
- locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
- }
-
- locationManager.requestLocation(withReGeocode: true) { (location: CLLocation!,reGeocode: AMapLocationReGeocode!, error: Error!) in
- if (error != nil) {
- return result(nil)
- }
- if (location != nil) {
- var dataMap: Dictionary<String, Any> = ["speed": location.speed ,"altitude": location.altitude, "latitude": location.coordinate.latitude, "longitude": location.coordinate.longitude, "accuracy": location.horizontalAccuracy, "bearing": location.course]
- if (reGeocode != nil) {
- dataMap["address"] = reGeocode.formattedAddress
- dataMap["country"] = reGeocode.country
- dataMap["city"] = reGeocode.city
- dataMap["street"] = reGeocode.street
- dataMap["district"] = reGeocode.district
- dataMap["province"] = reGeocode.province
- dataMap["adcode"] = reGeocode.adcode
- dataMap["citycode"] = reGeocode.citycode
- }
- result(dataMap)
- }
- }
- case "start":
- if let args = methodCall.arguments as? [String: Any] {
- interval = args["time"] as? Int ?? 2000
- var accuracy = args["accuracy"] as? Int
- if (accuracy == nil) {
- accuracy = 0
- }
- // 定位精度
- switch accuracy {
- case 1:
- locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
- case 2:
- locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
- case 3:
- locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
- case 4:
- locationManager.desiredAccuracy = kCLLocationAccuracyBest
- default:
- locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
- }
- timer?.invalidate()
- start = true
- timer = Timer.scheduledTimer(timeInterval:TimeInterval(interval / 1000), target: self, selector: #selector(sinkLocation(_:)), userInfo: nil, repeats: true)
- locationManager.stopUpdatingLocation()
- locationManager.pausesLocationUpdatesAutomatically = false
- locationManager.allowsBackgroundLocationUpdates = true
- locationManager.startUpdatingLocation()
- }
- result(nil)
- case "stop":
- locationManager.stopUpdatingLocation()
- timer?.invalidate()
- result(nil)
- case "enableBackground":
- //locationManager.stopUpdatingLocation()
- //locationManager.pausesLocationUpdatesAutomatically = false
- //locationManager.allowsBackgroundLocationUpdates = true
- //timer?.invalidate()
- //start = true
- //timer = Timer.scheduledTimer(timeInterval: TimeInterval(interval / 1000), target: self, selector: #selector(sinkLocation(_:)), userInfo: nil, repeats: true)
- //locationManager.startUpdatingLocation()
- result(nil)
- case "disableBackground":
- //locationManager.stopUpdatingLocation()
- //locationManager.allowsBackgroundLocationUpdates = false
- //timer?.invalidate()
- //start = true
- //timer = Timer.scheduledTimer(timeInterval: TimeInterval(interval / 1000), target: self, selector: #selector(sinkLocation(_:)), userInfo: nil, repeats: true)
- //locationManager.startUpdatingLocation()
- result(nil)
- default:
- result(FlutterMethodNotImplemented)
- }
- }
- @objc func sinkLocation(_ time:Timer) -> Void {
- if (mapLoca != nil) {
- eventSink?(mapLoca)
- }
- }
- func aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {
- self.fetchSink?(nil)
- }
-
- func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
- self.eventSink = events
- return nil
- }
-
- func onCancel(withArguments arguments: Any?) -> FlutterError? {
- return nil
- }
-
- func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
- if (location != nil) {
- var dataMap: Dictionary<String, Any> = ["speed": location.speed ,"altitude": location.altitude, "latitude": location.coordinate.latitude, "longitude": location.coordinate.longitude, "accuracy": location.horizontalAccuracy, "bearing": location.course]
- if (reGeocode != nil) {
- dataMap["address"] = reGeocode.formattedAddress
- dataMap["country"] = reGeocode.country
- dataMap["city"] = reGeocode.city
- dataMap["street"] = reGeocode.street
- dataMap["district"] = reGeocode.district
- dataMap["province"] = reGeocode.province
- }
- self.mapLoca = dataMap
- if (start) {
- self.eventSink?(dataMap)
- self.start = false
- }
-
- }
- }
-
- func amapLocationManager(_ manager: AMapLocationManager!, doRequireLocationAuth locationManager: CLLocationManager!) {
- locationManager.requestWhenInUseAuthorization()
- }
-
- func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
- self.fetchSink?(nil)
- }
-
- }
|