Как давно было зарегистрировано последнее известное местоположение?

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

LocationManager locationManager 
                        = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria c = new Criteria();
    c.setAccuracy(Criteria.ACCURACY_FINE);
    c.setAccuracy(Criteria.ACCURACY_COARSE);
    c.setAltitudeRequired(false);
    c.setBearingRequired(false);
    c.setCostAllowed(true);
    c.setPowerRequirement(Criteria.POWER_HIGH);
String provider = locationManager.getBestProvider(c, true);
Location location = locationManager.getLastKnownLocation(provider);

Ответ 1

Лучший вариант как для предварительного, так и для post API 17:

public int age_minutes(Location last) {
    return age_ms(last) / (60*1000);
}

public long age_ms(Location last) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
        return age_ms_api_17(last);
    return age_ms_api_pre_17(last);
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private long age_ms_api_17(Location last) {
    return (SystemClock.elapsedRealtimeNanos() - last
            .getElapsedRealtimeNanos()) / 1000000;
}

private long age_ms_api_pre_17(Location last) {
    return System.currentTimeMillis() - last.getTime();
}

Pre 17 не очень точен, но должен быть достаточным для проверки того, является ли местоположение очень старым.

Это, я думаю, будет ОК:

if (age_minutes(lastLoc) < 5) {
   // fix is under 5 mins old, we'll use it

} else {
   // older than 5 mins, we'll ignore it and wait for new one

}

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

Ответ 2

Извините, что повторно открыли это, но я думаю, что ответ Weston неверен, и документация на Android, по крайней мере, вводит в заблуждение.

Временная база для getTime() - это UTC, как определено из Предложение NMEA, полученное от модуля GPS, а не System.currentTimeMillis(). GPS время точно соответствует наносекундам (это должно быть, поскольку электромагнитные волны перемещаются на 30 см в 1 нс). только осложнение заключается в том, что оно может быть отключено на 1 с на второй шаг GPS (см. [1], это может случиться в течение нескольких минут каждые несколько лет, предполагая, что GPS достаточно интеллектуальный, чтобы запомнить смещение UTC в течение циклов мощности)

С другой стороны, System.currentTimeMillis() может быть отключен несколькими секунд/минут из-за дрейфа или даже больше, если пользователь неправильно устанавливает время/дату.

Итак, единственное реальное решение pre-API 17 регулярно получать обновления местоположения и каждый раз записывать ваша собственная временная метка на основе SystemClock.elapsedRealtime().

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

[1] http://en.wikipedia.org/wiki/Global_Positioning_System#Leap_seconds

Ответ 3

Location.getTime() на самом деле не лучший способ найти возраст последнего известного местоположения.

Из JavaDoc:

Возвратите время UTC этого исправления в миллисекундах с 1 января 1970 года.

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

Двумя используемыми способами являются:

SystemClock.elapsedRealtimeNanos();
Location.getElapsedRealtimeNanos();

Обратите внимание, что LocationManager.lastKnownLocation() может возвращать null.

Ответ 4

Каждое место имеет время атрибута. Получите его с помощью getTime(). Сравните его с текущим временем. (Рассчитайте разницу). Это дает вам "возраст".