LocationManager возвращает старое кэшированное местоположение "Wifi" с текущей отметкой времени - PullRequest
8 голосов
/ 16 июля 2011

Я пытаюсь получить текущее местоположение. Для этого я реализую 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 ]

6 голосов
/ 16 июля 2011

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

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

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

Сначала поймите, как работает сетевое местоположение: У Android есть идентификатор ячейки башни, к которой он в данный момент подключен, и этот идентификатор затем используется 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
    }
}
2 голосов
/ 17 июля 2011

Это полезно:

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

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

Android-protips-место

0 голосов
/ 03 декабря 2013

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

Произошло то, что я подключал один и тот же 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). Не уверен, что это работает для вас.

...