Как разработчик SpeedView: GPS-спидометр для Android, я, должно быть, перепробовал все возможные решения этой проблемы, и все с тем же отрицательным результатом. Повторим, что не работает:
- onStatusChanged () не вызывается в Eclair и Froyo.
- Просто подсчитывать все доступные спутники, конечно, бесполезно.
- Проверка того, возвращает ли какой-либо из спутников true для usedInFix (), также не очень полезна. Система явно теряет исправление, но продолжает сообщать, что в ней все еще используются несколько спутников.
Итак, вот единственное рабочее решение, которое я нашел, и то, которое я использую в своем приложении. Допустим, у нас есть этот простой класс, который реализует GpsStatus.Listener:
private class MyGPSListener implements GpsStatus.Listener {
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
if (mLastLocation != null)
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
if (isGPSFix) {
} else {
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
isGPSFix = true;
break;
}
}
}
Хорошо, теперь в onLocationChanged () мы добавляем следующее:
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
mLastLocationMillis = SystemClock.elapsedRealtime();
mLastLocation = location;
}
Вот и все. По сути, это строка, которая все делает:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000
Конечно, вы можете настроить значение в миллисекундах, но я бы посоветовал установить его примерно на 3-5 секунд.
Это действительно работает, и хотя я не смотрел исходный код, который рисует собственный значок GPS, это почти повторяет его поведение. Надеюсь, это кому-то поможет.