在不耗尽电池的情况下以良好的准确性获取位置更新的最佳方法
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 秒或当用户移动阈值而不耗尽电池时获得高精度位置?