在不耗尽电池的情况下以良好的准确性获取位置更新的最佳方法

Posted

技术标签:

【中文标题】在不耗尽电池的情况下以良好的准确性获取位置更新的最佳方法【英文标题】:Best way to get LocationUpdates with a good Accuracy without draining down the Battery 【发布时间】:2017-01-27 01:07:37 【问题描述】:

我一直在尝试实现一个 LocationView 控制器,它不断将用户位置更新到服务器。当我调试应用程序并在使用时我注意到,我提供的源代码比平时更快地耗尽了我的手机电池。我是否必须解决这个问题,或者有什么方法可以在不减少 LocationRequirements 的情况下改善以下代码中的 PowerUsage?

class LocationViewController: UIViewController 
  // MARK: - Outlets
  @IBOutlet var mapView: MKMapView!

  fileprivate var locations = [MKPointAnnotation]()
  var updatesEnabled: Bool = false;

  var defaultCentre: NotificationCenter = NotificationCenter.default
  //- NSUserDefaults - LocationServicesControl_KEY to be set to TRUE when user has enabled location services.
  let UDefaults: UserDefaults = UserDefaults.standard;
  let LocationServicesControl_KEY: String = "LocationServices"


  public var lastPosition: Date?;

  public lazy var locationManager: CLLocationManager = 
    let manager = CLLocationManager()
    manager.distanceFilter = 20;
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.delegate = self
    manager.requestAlwaysAuthorization()
    return manager
  ()

  public var routeLine: MKPolyline = MKPolyline() //your line
  public var routeLineView: MKPolylineView = MKPolylineView(); //overlay view
  // MARK: - Actions
  @available(ios 9.0, *)
  @IBAction func enabledChanged(_ sender: UISwitch) 
    if sender.isOn 
      self.UDefaults.set(true, forKey: self.LocationServicesControl_KEY)
      locationManager.startUpdatingLocation()
      locationManager.allowsBackgroundLocationUpdates = true
      self.updatesEnabled = true;
     else 
      self.UDefaults.set(false, forKey: self.LocationServicesControl_KEY)
      locationManager.stopUpdatingLocation()
      self.updatesEnabled = false;
      self.timer.invalidate()
      locationManager.allowsBackgroundLocationUpdates = false
    
  

  @IBAction func accuracyChanged(_ sender: UISegmentedControl) 
    let accuracyValues = [
      kCLLocationAccuracyBestForNavigation,
      kCLLocationAccuracyBest,
      kCLLocationAccuracyNearestTenMeters,
      kCLLocationAccuracyHundredMeters,
      kCLLocationAccuracyKilometer,
      kCLLocationAccuracyThreeKilometers]
    locationManager.desiredAccuracy = accuracyValues[sender.selectedSegmentIndex];
  

  // MARK: - Override UIViewController
  override func viewDidLoad() 
    mapView.delegate = self;
  


// MARK: - MKMapViewDelegate
extension LocationViewController: MKMapViewDelegate 
  func addRoute() 
    mapView.remove(self.routeLine);
    var pointsToUse: [CLLocationCoordinate2D] = [];
    for i in locations 
      pointsToUse += [i.coordinate];
    
    self.routeLine = MKPolyline(coordinates: &pointsToUse, count: pointsToUse.count)
    mapView.add(self.routeLine)
  


// MARK: - CLLocationManagerDelegate
extension LocationViewController: CLLocationManagerDelegate 

  func isUpdateValid (newDate: Date) -> Bool
    var interval = TimeInterval()
    if(lastPosition==nil)lastPosition=newDate
    interval = newDate.timeIntervalSince(lastPosition!)
    if ((interval==0)||(interval>=self.UpdatesInterval))
      return true
     else 
      return false
    
  

  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 
    guard let mostRecentLocation = locations.last else 
      return
    
    if(isUpdateValid(newDate: mostRecentLocation.timestamp))
      let position = MKPointAnnotation();
      position.coordinate=mostRecentLocation.coordinate;
      self.locations.append(position);
      self.addRoute();

      self.locationAPI.postLocation(location: mostRecentLocation)
      lastPosition=mostRecentLocation.timestamp
    
  

【问题讨论】:

使用kCLLocationAccuracyBest 会在 GPS 开机时耗尽电池电量。建议您仅在设备使用外部电源时长时间使用此设置。您可以使用较低的精度设置或显着位置更改以减少功耗。 【参考方案1】:

您需要以某种方式限制 GPS“点亮”的时间。如果您将其设置为不断提供高精度 GPS 读数,它将保持 GPS 通电并且您将使用大量电力。没有什么可做的。

可能性:

您可以每 10 分钟唤醒一次 GPS,运行它直到获得良好读数,然后再将其关闭。

当您的应用首次启动时,您会获得良好的阅读,然后订阅重大的位置更改,当您获得更新时,开始位置更新,获得新的修复,然后再次关闭位置更新。

我不确定您会如何选择第一个选项,因为 Apple 不允许您的应用在后台无限期地运行。您需要您的应用始终处于唤醒状态并在前台运行,这也会比允许进入睡眠状态时更快地消耗电池电量。

【讨论】:

以上是关于在不耗尽电池的情况下以良好的准确性获取位置更新的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

Google Fit 应用程序如何在不耗尽电池电量的情况下一直测量步数?

如何每 5 秒或当用户移动阈值而不耗尽电池时获得高精度位置?

搜索位置时防止 GPS 耗尽手机电池

在用户不认为他们的电池会耗尽的情况下使用显着的位置变化

是否可以在不替换的情况下以编程方式修改/更新 plist 文件?

使用 gps 捕获经纬度而不会耗尽电池电量