CLLocationManager работает в фоновом режиме и энергосбережения
Я работаю над iOS tracer. Он должен запускаться и получать местоположения, даже если приложение не на переднем плане, т.е. я использую фоновый режим "Обновления местоположения". Тем не менее, было бы хорошо, если это возможно. В частности, нет необходимости получать местоположения, если устройство не двигается.
- Я пытался установить
distanceFilter
наCLLocationManager
экземпляр, но это не экономит электроэнергию, оно просто уменьшает количество обновлений местоположения. - Я не могу остановиться и запустить диспетчер местоположения вручную, так как приложение будет приостановлено, если в фоновом режиме.
- Я пытался использовать диспетчер местоположения с
pausesLocationUpdatesAutomatically
установлен вYES
(он включен по умолчанию), но если приложение находится в фоновом режиме и обновления местоположения приостановлены, приложение приостанавливается и не активируется, даже если устройство снова начинает двигаться.
Есть ли способ экономии батареи, когда мне нужно получить местоположение в фоновом режиме? Флаг pausesLocationUpdatesAutomatically
это очень близко к тому, что я ищу, но приостановка приложения в фоновом режиме является для меня ограничителем показа.
2 ответа
То, что вы ищете, это
- allowDeferredLocationUpdatesUntilTraveled:timeout:
Если ваше приложение работает в фоновом режиме, и система способна оптимизировать энергопотребление, диспетчер местоположений сообщает оборудованию GPS, чтобы оно сохраняло новые местоположения внутри до тех пор, пока не будут соблюдены указанное расстояние или время ожидания. Когда один или оба критерия удовлетворены, диспетчер местоположений заканчивает отложенные местоположения, вызывая locationManager: didFinishDeferredUpdatesWithError: метод его делегата и доставляет кэшированные местоположения в locationManager: didUpdateLocations: метод.
ех;
[locationManager allowDeferredLocationUpdatesUntilTraveled:100.0f timeout:CLTimeIntervalMax];
Таким образом, в основном это сэкономит некоторую вычислительную мощность, посылая обновления местоположения в виде коллекции местоположения через определенное время, а не вызывая обратный вызов обновления местоположения каждый раз, когда устройство регистрирует движение.
И вы можете получить обновление местоположения с помощью следующего метода обратного вызова;
-(void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error
Использование "отложенных обновлений местоположения", как упомянуто Лаки, вероятно, является единственным возможным способом экономии энергии для приложения, которое должно работать в фоновом режиме и не может быть приостановлено. Я просто хочу обобщить то, что я узнал, экспериментируя с этой функцией:
Приостановка приложения может быть запрещена, то есть свойство
pausesLocationUpdatesAutomatically
можно установить наNO
в случаеCLLocationManager
и отложенные обновления местоположения будут работать в любом случае.При звонке
allowDeferredLocationUpdatesUntilTraveled: timeout:
в качестве параметров должно быть указано некоторое расстояние и некоторое время ожидания. Если вы предоставите слишком низкие значения, функция не вступит в силу. Тайм-аут 80 секунд слишком мал, 90 секунд в порядке. Расстояние 90 метров слишком мало, 100 метров в порядке. (протестировано на iPhone 5, iOS 8.4.1)Я не уверен, что эта функция вступит в силу, если приложение находится в фоновом режиме. Я не наблюдал это до сих пор. Однако это может вступить в силу, если экран заблокирован.
Эта функция не вступает в силу сразу после блокировки экрана. Вы должны подождать некоторое время. Это было 30 - 150 секунд в моих наблюдениях.
Система иногда не доставляет обновления местоположения партиями. Мое тестовое приложение работало в фоновом режиме 13 часов с заблокированным экраном, и 38% этого времени оно получало местоположения один за другим. Только оставшиеся 62% времени выполнения он получал партии локаций (сбор как минимум с двумя элементами). Устройство не двигалось вообще.
Эта функция не вступит в силу, если устройство подключено с помощью стыковочного кабеля к Mac и приложение работает в отладчике.
Эта функция поддерживается не всеми устройствами, например, не поддерживается iPhone 4 или iPad 2.
Я сделал несколько измерений, чтобы проверить, сколько энергии сэкономлено. Я запускаю приложение на iPhone 5, iOS 8.4.1 в фоновом режиме с заблокированным экраном. Приложение только запускает
CLLocationManager
и сохраняет статистику о полученных данных о местоположении (используяNSUSerDefaults
), чтобы можно было просмотреть их при следующем запуске приложения. Wi-Fi соединение было отключено, сотовая связь включена. Батарея была полностью заряжена, другие приложения не работали. Устройство не двигалось и было положено на место с сигналом GPS. Благодаря отложенному обновлению местоположения (с минимальным расстоянием 900 метров и временем ожидания 90 секунд) батарея полностью разрядилась за 15,25 часа. Без отложенного обновления местоположения это заняло 13 часов.