AmapLocationFactory.swift 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //
  2. // AmapLocationFactory.swift
  3. // amap_location
  4. //
  5. // Created by QiuLiang Wang on 2020/6/5.
  6. //
  7. import Foundation
  8. import AMapFoundationKit
  9. import AMapLocationKit
  10. class AmapLocationFactory: NSObject, AMapLocationManagerDelegate, FlutterStreamHandler {
  11. private var messenger: FlutterBinaryMessenger
  12. private var locationManager: AMapLocationManager
  13. private var eventSink: FlutterEventSink?
  14. private var timer: Timer?
  15. private var interval: Int = 2000
  16. private var start: Bool = true
  17. private var mapLoca: Dictionary<String, Any>?
  18. private var fetchLoca: Dictionary<String, Any>?
  19. private var fetchSink: FlutterResult?
  20. init(withMessenger messenger: FlutterBinaryMessenger) {
  21. self.messenger = messenger
  22. locationManager = AMapLocationManager()
  23. super.init()
  24. locationManager.distanceFilter = 5
  25. locationManager.delegate = self
  26. locationManager.locatingWithReGeocode = false
  27. locationManager.allowsBackgroundLocationUpdates = true
  28. }
  29. func register() {
  30. let channel = FlutterMethodChannel(name: "plugins.ouj.com/amap_location", binaryMessenger:messenger)
  31. channel.setMethodCallHandler(onMethodCall)
  32. let event = FlutterEventChannel(name: "plugins.ouj.com/amap_location_event", binaryMessenger: messenger)
  33. event.setStreamHandler(self)
  34. }
  35. func onMethodCall(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
  36. switch methodCall.method {
  37. case "fetch":
  38. let args = methodCall.arguments as? [String: Any]
  39. var accuracy = args?["accuracy"] as? Int
  40. if (accuracy == nil) {
  41. accuracy = 0
  42. }
  43. // 定位精度
  44. switch accuracy {
  45. case 1:
  46. locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
  47. case 2:
  48. locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
  49. case 3:
  50. locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
  51. case 4:
  52. locationManager.desiredAccuracy = kCLLocationAccuracyBest
  53. default:
  54. locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
  55. }
  56. locationManager.requestLocation(withReGeocode: true) { (location: CLLocation!,reGeocode: AMapLocationReGeocode!, error: Error!) in
  57. if (error != nil) {
  58. return result(nil)
  59. }
  60. if (location != nil) {
  61. 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]
  62. if (reGeocode != nil) {
  63. dataMap["address"] = reGeocode.formattedAddress
  64. dataMap["country"] = reGeocode.country
  65. dataMap["city"] = reGeocode.city
  66. dataMap["street"] = reGeocode.street
  67. dataMap["district"] = reGeocode.district
  68. dataMap["province"] = reGeocode.province
  69. dataMap["adcode"] = reGeocode.adcode
  70. dataMap["citycode"] = reGeocode.citycode
  71. }
  72. result(dataMap)
  73. }
  74. }
  75. case "start":
  76. if let args = methodCall.arguments as? [String: Any] {
  77. interval = args["time"] as? Int ?? 2000
  78. var accuracy = args["accuracy"] as? Int
  79. if (accuracy == nil) {
  80. accuracy = 0
  81. }
  82. // 定位精度
  83. switch accuracy {
  84. case 1:
  85. locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
  86. case 2:
  87. locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
  88. case 3:
  89. locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
  90. case 4:
  91. locationManager.desiredAccuracy = kCLLocationAccuracyBest
  92. default:
  93. locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
  94. }
  95. timer?.invalidate()
  96. start = true
  97. timer = Timer.scheduledTimer(timeInterval:TimeInterval(interval / 1000), target: self, selector: #selector(sinkLocation(_:)), userInfo: nil, repeats: true)
  98. locationManager.stopUpdatingLocation()
  99. locationManager.pausesLocationUpdatesAutomatically = false
  100. locationManager.allowsBackgroundLocationUpdates = true
  101. locationManager.startUpdatingLocation()
  102. }
  103. result(nil)
  104. case "stop":
  105. locationManager.stopUpdatingLocation()
  106. timer?.invalidate()
  107. result(nil)
  108. case "enableBackground":
  109. //locationManager.stopUpdatingLocation()
  110. //locationManager.pausesLocationUpdatesAutomatically = false
  111. //locationManager.allowsBackgroundLocationUpdates = true
  112. //timer?.invalidate()
  113. //start = true
  114. //timer = Timer.scheduledTimer(timeInterval: TimeInterval(interval / 1000), target: self, selector: #selector(sinkLocation(_:)), userInfo: nil, repeats: true)
  115. //locationManager.startUpdatingLocation()
  116. result(nil)
  117. case "disableBackground":
  118. //locationManager.stopUpdatingLocation()
  119. //locationManager.allowsBackgroundLocationUpdates = false
  120. //timer?.invalidate()
  121. //start = true
  122. //timer = Timer.scheduledTimer(timeInterval: TimeInterval(interval / 1000), target: self, selector: #selector(sinkLocation(_:)), userInfo: nil, repeats: true)
  123. //locationManager.startUpdatingLocation()
  124. result(nil)
  125. default:
  126. result(FlutterMethodNotImplemented)
  127. }
  128. }
  129. @objc func sinkLocation(_ time:Timer) -> Void {
  130. if (mapLoca != nil) {
  131. eventSink?(mapLoca)
  132. }
  133. }
  134. func aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {
  135. self.fetchSink?(nil)
  136. }
  137. func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
  138. self.eventSink = events
  139. return nil
  140. }
  141. func onCancel(withArguments arguments: Any?) -> FlutterError? {
  142. return nil
  143. }
  144. func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
  145. if (location != nil) {
  146. 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]
  147. if (reGeocode != nil) {
  148. dataMap["address"] = reGeocode.formattedAddress
  149. dataMap["country"] = reGeocode.country
  150. dataMap["city"] = reGeocode.city
  151. dataMap["street"] = reGeocode.street
  152. dataMap["district"] = reGeocode.district
  153. dataMap["province"] = reGeocode.province
  154. }
  155. self.mapLoca = dataMap
  156. if (start) {
  157. self.eventSink?(dataMap)
  158. self.start = false
  159. }
  160. }
  161. }
  162. func amapLocationManager(_ manager: AMapLocationManager!, doRequireLocationAuth locationManager: CLLocationManager!) {
  163. locationManager.requestWhenInUseAuthorization()
  164. }
  165. func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
  166. self.fetchSink?(nil)
  167. }
  168. }