Android Kotlin: получение местоположения, когда приложение находится в спящем режиме

Я пытаюсь получить текущее местоположение пользователя приложения каждые 2 секунды.

Я уже использую службу переднего плана с уведомлением (можно записывать местоположение, когда приложение находится в фоновом режиме). Но когда приложение переходит в режим ожидания, оно будет продолжать указывать 3 местоположения после того, как экран станет черным. Но тогда перестанет сообщать мне обновления местоположений.

Я использую FusedLocationProviderClient, чтобы узнать свое текущее местоположение. У меня есть WakeLock, чтобы служба работала, и это работает. Чтобы проверить это, у меня запущена корутина, и я могу сделать println("test"), но когда я хочу свое местоположение, я ничего не получаю.

fusedLocationProviderClient?.getCurrentLocation(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, cancellationSource?.token)?
.addOnSuccessListener {
   val loc = it
   println("${loc.latitude},${loc.longitude}")
   postNewLocation(loc)
}?.addOnCanceledListener {
     println("cancel")
}

Сразу после того, как я получаю последнее обновление местоположения, я получаю это LocationEngineResult == null.

Кто-нибудь знает, что я делаю неправильно? Любая помощь или советы были бы замечательными.

Для контекста я использую Android 11 с targetdkversion 30.

Я новичок в kotlin, и это для школьного проекта, который я должен завершить.


person SimonBettens    schedule 27.11.2020    source источник


Ответы (1)


Вы не можете получать данные о местоположении, когда устройство находится в спящем режиме. Цитирование комментария представителя Google по проблеме в системе отслеживания проблем Google:

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

Справочник

Примечание.
Вы можете сказать, что режим ожидания не должен влиять на Foreground Service. Нет, это не так. Это провайдер местоположения.

Обновление:
Doze режим активируется только в том случае, если пользователь оставляет устройство отключенным от сети и неподвижно на некоторое время с выключенным экраном. Таким образом, если устройство стационарно находится в одном месте, нет необходимости отслеживать местоположение в течение этого периода времени.

Не знаю, является ли режим Doze вашей проблемой. Оптимизация батареи — еще одна проблема. Для некоторых телефонов поставщики данных о местоположении отключаются, когда включена оптимизация батареи и выключен экран. Вы можете проверить это поведение, используя PowerManager.getLocationPowerSaveMode(). Режимы:

  1. LOCATION_MODE_FOREGROUND_ONLY
  2. LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF
  3. LOCATION_MODE_NO_CHANGE
  4. LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF

Кроме того, некоторые производители телефонов создали телефоны, которые не соответствуют стандартному поведению Android. Проверьте это.

person Keyser Söze    schedule 27.11.2020
comment
Спасибо за ваш ответ. Но мне интересно, как Strava и другие подобные приложения отслеживают местоположение пользователей, когда телефон находится в спящем режиме? - person SimonBettens; 28.11.2020
comment
Они не делают. Режим Doze активируется, только если пользователь покидает устройство отключено от сети и неподвижно в течение определенного периода времени с выключенным экраном. Таким образом, если устройство стационарно находится в одном месте, нет необходимости отслеживать местоположение в течение этого периода времени. - person Keyser Söze; 28.11.2020
comment
Хорошо, еще раз спасибо! У меня был друг и сокурсник, тестировавший приложение, и проблемы, которые, как я думал, у меня были с режимом дремоты, на самом деле были не так. Проблема была в том, что я использовал эмулятор, а не реальное устройство. Еще раз спасибо за помощь мне - person SimonBettens; 28.11.2020