Подтвердить что ты не робот

Слив батареи при использовании CoreLocation Значительный мониторинг местоположения и CoreBluetooth

Мы выпустили приложение, которое работает в фоновом режиме и использует CoreBluetooth и CoreLocation для автоматического сохранения вашего места парковки.

На высоком уровне наше приложение просто ищет событие отключения CoreBluetooth и включает GPS, пока мы не получим исправление местоположения (точность <= 10 м) или максимальное время в 3 минуты (это может произойти, если вы припарковаетесь в подземном автостоянка без GPS-покрытия). Затем мы используем "Значительный мониторинг местоположения" для автоматического повторного запуска нашего приложения в случае, если система завершает наше приложение.

Во время нашего развития мы никогда не видели проблемы с истощением батареи, однако 75% наших пользователей говорят, что они видят значительный разряд батареи. 10% наших сторонников ответили на опрос, поэтому сложно определить, насколько репрезентативным является разбивка, но это большой процент наших пользователей. http://www.findmycarsmarter.com/forum/viewtopic.php?f=4&t=30

Затем мы выпустили обновление, которое позволило пользователям отключить значительный мониторинг местоположения, а 60% сказали, что, отключив значительный мониторинг местоположения, утечка уходит. http://www.findmycarsmarter.com/forum/viewtopic.php?f=4&t=42

Изначально мы не могли дублировать проблему утечки самостоятельно, но мы обнаружили, что когда мы установили простое приложение, которое только что включило "Мониторинг значимых местоположений" вместе с Find My Car Smarter, мы периодически видели, как дренаж воспроизводится. В состоянии слива телефон не переходит в спящий режим. Это указывается временем использования в (Настройки- > Использование- > Время с момента последней полной зарядки), продолжая увеличиваться, даже если телефон был усыпан и дисплей выключен. Что-то мешает системе входить в спящий режим. На этом этапе батарея разряжается на 15% в час. Этот сток проявляется с перерывами и, кажется, проясняется через час или два и приходит случайно. Мы не нашли способ повысить надежность утечки.

Мы полагаем, что проблема вызвана тем, что несколько клиентов обращаются к CoreLocation. Мы попросили нескольких пользователей, которые столкнулись с проблемой, стереть их телефон и установить только приложение Find My Car Smarter. Один только с этим приложением установлено, слив не показывался. У нас были другие отчеты о том, что когда наше приложение используется с Google Latitude или Facebook и т.д., Когда они видят, что происходит утечка. Или, если они идут и убивают другие приложения, утечка уходит. Мы видели, что утечка сохраняется через силовой цикл, без запуска приложений. Это означает, что это должен быть сервис системного уровня, который не позволяет ОС спать.

Несмотря на то, что мы думаем, что проблема связана с некоторыми состояниями гонки нескольких клиентов, обращающихся в CoreLocation, мы никогда не видели, чтобы проблема воспроизводилась с приложениями, которые использовали CoreLocation. Мы даже создали 4 или 5 различных приложений, которые будут одновременно получать доступ к CoreLocation, и мы не видели, как происходит утечка. Однако мы видели проблему, когда у нас было приложение с CoreLocation и второе приложение с CoreLocation + CoreBluetooth. Есть, вероятно, очень мало приложений, которые используют комбинацию CoreLocation + CoreBluetooth, поэтому потенциально это может быть связано с тем, что другие разработчики не попали в эту проблему. Хотя мы не в состоянии объяснить, как взаимодействуют CoreLocation и CoreBluetooth, чтобы вызвать утечку и как второе приложение с CoreLocation входит в уравнение. Поскольку утечка была прерывистой, возможно, что это просто случайность, что проблема произошла только при тестировании с помощью CoreLocation + CoreBluetooth.

На очищенном 5.0.1 iPhone 4S с установленными только этими двумя приложениями CTM1 и FMC мы смогли переходить в состояние стока. Интересно, что проблема утечки, по-видимому, происходила гораздо реже на протертом устройстве, а затем на нашем обычном устройстве. К сожалению, мы только видели состояние стока несколько раз и без возможности надежного воспроизведения стока, у нас нет хорошего состояния управления для работы.

Мы опубликовали отчет об ошибке с Apple и открыли инцидент с технической поддержкой, но, возможно, сообщество Stackover также может дать некоторое представление. Мы видели эту проблему как в версии 5.0.1, так и в версии 5.1 Beta 3.

CTM1 http://www.findmycarsmarter.com/files/CTM1.zip

On Going into the Background
    [locationManager stopUpdatingLocation];
    [locationManager stopUpdatingHeading];
    [locationManager startMonitoringSignificantLocationChanges];

On Re-entering Foreground
    [locationManager stopMonitoringSignificantLocationChanges];
    [locationManager startUpdatingLocation];
    [locationManager startUpdatingHeading];
On didUpdateToLocation
    //do nothing
On didUpdateHeading
    //do nothing

FMC http://www.findmycarsmarter.com/files/FMC.zip

On Going into the Background
    [btleManager stopScan];
    [locationManager stopUpdatingLocation];
    [locationManager stopUpdatingHeading];
    [locationManager startMonitoringSignificantLocationChanges];

On Re-entering Foreground
    [locationManager stopMonitoringSignificantLocationChanges];
    [locationManager startUpdatingLocation];
    [locationManager startUpdatingHeading];        
    [btleManager scanForPeripheralsWithServices:nil options:nil];
On didUpdateToLocation
    //do nothing
On didUpdateHeading
    //do nothing
On centralManagerDidUpdateState
    [btleManager scanForPeripheralsWithServices:nil options:nil];
On didDiscoverPeripheral
    [btleManager connectPeripheral:device options:nil];
On didConnectPeripheral
    //update log
On didDisconnectPeripheral
    //initiate reconnect
    [btleManager connectPeripheral:device options:nil];

Если вы видите ошибки в кодировке, которые могли бы учитывать утечку, сообщите нам об этом.

Еще один вопрос, который у нас был, если мы используем GPS и значительный мониторинг местоположения, есть ли причина для вызова stopMonitoringSignificantLocationChanges? Глядя на примерный код регионов, они вызывают stopMonitoringSignificantLocationChanges и startLocationUpdate при вводе переднего плана и stopLocationUpdate и startMonitoringSignificantLocationChanges при вводе фона, но мне интересно, нужно ли это/рекомендуется/требуется?

Update:

Мы подтвердили с технической поддержкой Apple Developer, что для приложений, использующих как GPS, так и значимый мониторинг местоположения, наша последовательность отключения значительного мониторинга местоположения, прежде чем включить обновление GPS, верна.

Мы также подтвердили, что проблема утечки все еще может быть замечена в GM 5.1 и с помощью скомпилированного приложения Find My Car Smarter против 5.1 Framework.

Update:

Похоже, проблема возникает, когда наше приложение запускается из фона в ответ на событие "Значительное обнаружение местоположения". Мы фактически не обрабатываем этот сценарий должным образом в нашем примере кода, но делаем это в нашем реальном приложении.

В примере кода, при повторном запуске фона мы включим обновление местоположения, и поскольку не будет вызова applicationDidEnterBackground, GPS будет оставлен.

В нашем приложении мы проверяем, запускались ли мы из фона, ища флаг UIApplicationLaunchOptionsLocationKey, если мы начнем Значительный мониторинг местоположения, иначе мы были запущены на переднем плане, и мы начнем обновление местоположения.

Apple вернулась к нам и заявила, что использование значимого мониторинга местоположения не требует определения местоположения в массиве UIBackgroundModes в Info.plist. Мы удалили эту запись, и кажется, что состояние слива батареи больше не попадает. У нас все еще есть bluetooth-central в списке UIBackgroundModes. На данный момент мы неясны, почему это помогает. Мы собираемся провести еще несколько экспериментов, чтобы помочь нам понять это лучше. Если у кого-нибудь есть предложения, сообщите нам.

4b9b3361

Ответ 1

В конце дня предложение Apple об удалении местоположения из UIBackgroundModes устранило проблему утечки батареи.

Чтобы по-прежнему получать места в фоновом режиме, нам пришлось обернуть вызовы [locationManager startLocationUpdates] и [locationManager stopLocationUpdates] с помощью:

[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler];
[[UIApplication sharedApplication] endBackgroundTask:];

Ответ 2

Вы можете отлаживать статус приложения, используя любой повторяющийся звуковой сигнал. Просто убедитесь, что вы не поместили "воспроизведение аудио" в требованиях к фоновым режимам для этого теста. Если ваше приложение работает - вы услышите этот звук, даже приложение находится в фоновом режиме. Если приложение приостановлено, вы ничего не услышите. Это, вероятно, самый простой способ обнаружить, что приложение не было приостановлено.

Использование Profiler для отладки этой проблемы является проблематичным, поскольку во время работы устройства, подключенного к компьютеру, многие вещи работают по-разному. Особенно энергосберегающие вещи.

Кроме того, убедитесь, что все сделано правильно в ответ на значительные изменения местоположения. Если вы начнете обновление местоположения, убедитесь, что вы установили некоторый таймер (например, в течение 3 минут), который отключает обновления местоположения. Во всяком случае, iOS убьет вас, даже если он начнет обновление местоположения от ответа на значительные изменения местоположения. Неважно, что вы начали в ответ - приложение будет убито за 10 минут, если все еще работает, обратите внимание на журналы сбоев - там будет зарегистрировано такое событие.

Кроме того, проверьте все свои сторонние коды и библиотеки - возможно, некоторые из них превращают GPS и используют его для чего-то. В основном параноидальный, но может произойти для целей аналитического и рекламного таргетинга.

Ответ 3

Приложения с поддержкой CoreLocation обычно выполняются в фоновом режиме, поэтому они могут работать в фоновом режиме, определенно, это больше использует аккумулятор, поскольку мое предложение всегда пытается остановить службу определения местоположения, когда это не нужно.

[locationManager stopUpdatingLocation];

а затем, согласно вашему требованию, начните, соответственно,

Спасибо