LocationManager возвращает старое кэшированное местоположение "Wifi" с текущей отметкой времени

Я пытаюсь узнать текущее местоположение. Для этого я реализую LocationListener и регистрирую его как для сети, так и для поставщика GPS:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

Затем я блокирую на 30 секунд и использую первое местоположение, которое передается в слушателя

onLocationChanged()

метод с точностью до 100 метров или лучше.

В большинстве случаев это работает нормально. Если телефон подключен к какой-либо сети Wi-Fi, требуется всего лишь секунда, чтобы найти правильное местоположение с точностью около 50 метров. Если нет Wi-Fi, но GPS включен, конечно, это может занять некоторое время, чтобы найти местоположение.

Иногда, однако, при подключении к Wi-Fi и получении текущего местоположения, предоставляется какое-то старое (кэшированное?) Предыдущее местоположение "Wi-Fi" - это может быть 15 минут и 15 километров от текущего местоположения. Проблема в том, что

location.getTime()

возвращает текущее время - поэтому невозможно знать, что местоположение старое.

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

3 ответа

Решение

Это полезно:

Глубокое погружение в локацию

и, наконец, исходный код для этого разговора:

андроид-protips-место

Это известная проблема, с которой я столкнулся и провел некоторое исследование того, почему это происходит.

Вот мои наблюдения:

  • Обычно это происходит, когда передача обслуживания мобильной сети происходит после потери подключения к сети, что не обязательно может быть достаточно значительным для реализации пользователем.
  • Предположим, что вы садитесь на поезд метро, ​​и вы садитесь на станцию ​​A и спускаетесь на станцию ​​B, теперь, когда вы садитесь на станцию ​​B, идентификатор сетевой ячейки может / не может все еще принадлежать станции A, и, конечно, она будет делать выкл и переезд на станцию ​​Б.
  • Однако, если вы позвоните, чтобы getLocation был активен до передачи обслуживания, вы получите местоположение станции A, которое может быть примерно в 10 км и 15 минутах назад.

Сначала поймите, как работает сетевое местоположение: у Android есть cellId башни, к которой он в данный момент подключен, и этот идентификатор затем используется Google для поиска и получения приблизительной информации о местоположении, точность которой может варьироваться от 50 метров (один из лучше всего) до нескольких тысяч метров. Если cellId неверен, как показано в приведенном выше примере, вы получите неправильное местоположение.

Вы можете сделать немногое, чтобы избежать этого, кроме наличия собственного алгоритма, который может отсеять этот шум. Что-то вроде

if (location from network) {
    if (speed obtained from the difference between previous and current location is        greater than say 30 m/s) {
        ignore this location as noise
    } else {
       location is correct
    }
}

Я сталкивался с теми же проблемами, пока не сделал некоторые изменения в своем коде.

Случилось так, что я подключал один и тот же LocationListener при запросе обновлений GPS и сетевого местоположения, и у меня возникали "странные" проблемы, включая получение старых обновлений местоположения WIFI с текущим временем.

Вот мой старый код:

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, locationListener);

Очевидно, это довольно "небезопасная" вещь (извините, новичок Android здесь), и поэтому я изменил ее на:

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, networkLocationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, gpsLocationListener);

Конечно, мне пришлось определить 2 отдельных блока кодов onLocationChanged для обработки 2 слушателей.

Ну, это решило мою проблему. Я проверял это на Gingerbread (уровень API: 8). Не уверен, что это работает для вас.

Другие вопросы по тегам