Как постоянно отслеживать местоположение мобильного телефона Android?

Мне нужно написать приложение, которое каждые 5 минут определяет текущее местоположение мобильного телефона (используя всех бесплатных, доступных провайдеров местоположения) и отправляет его на сервер.

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

Для этого я реализовал следующий класс. В одном из моих действий я создаю его экземпляр и называю егоstartTrackingUpdates метод.locationChangeHandler выполняет обработку данных о местоположении.

public class LocationTracker implements ILocationTracker, LocationListener {
    public static final long MIN_TIME_BETWEEN_UPDATES = 1000 * 60 * 5; // 5 minutes
    public static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
    private ILocationManager locationManager;
    private ILocationChangeHandler locationChangeHandler;

    public LocationTracker(final ILocationManager aLocationManager,
            final ILocationChangeHandler aLocationChangeHandler) {
        this.locationManager = aLocationManager;
        this.locationChangeHandler = aLocationChangeHandler;
    }

    public void startTrackingUpdates() {
        final List<String> providers = locationManager.getAllProviders();

        for (final String curProviderName : providers)
        {
            final ILocationProvider provider = locationManager.getLocationProvider(curProviderName);

            if (!provider.hasMonetaryCost())
            {
                subscribeToLocationChanges(provider);
            }
        }
    }

    private void subscribeToLocationChanges(final ILocationProvider aProvider) {
        locationManager.requestLocationUpdates(aProvider.getName(), MIN_TIME_BETWEEN_UPDATES, 
                (float)MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
    }

    public void onLocationChanged(final Location aLocation) {
        locationChangeHandler.processLocationChange(new LocationWrapper(aLocation));
    }

    public void onProviderDisabled(final String aProvider) {
    }

    public void onProviderEnabled(final String aProvider) {
    }

    public void onStatusChanged(final String aProvider, final int aStatus, 
            final Bundle aExtras) {
    }
}

Я собрал приложение и установил его на свой мобильный телефон. Утром я взял телефон, пошел на работу и вернулся домой. Дома я проверил результаты однодневной работы приложения и нашел только одну запись в базе данных.

При условии, что остальная часть системы (передача данных о местоположении на сервер, сохранение в базе данных) работает правильно, у меня должны быть некоторые проблемы с кодом отслеживания местоположения (onLocationChanged не вызывался, хотя я несколько раз менял свое местоположение).

Что не так с моим кодом (как я должен изменить его, чтобыonLocationChanged вызываться всякий раз, когда местоположение телефона изменяется более чем наMIN_DISTANCE_CHANGE_FOR_UPDATES метров по словам одного из провайдеров местонахождения)?

Обновление 1 (18.08.2013 13:59 мск):

Я изменил свой код в соответствии сMSH рекомендации. Я запускаю таймер, используя следующий код:

public void startSavingGeoData() {
    final IAlarmManager alarmManager = activity.getAlarmManager();
    final IPendingIntent pendingIntent = activity.createPendingResult(
            ALARM_ID, intentFactory.createEmptyIntent(), 0);
    alarmManager.setRepeating(INTERVAL, pendingIntent);
}

вactivity Я поставил следующий обработчик событий таймера:

@Override
protected void onActivityResult(final int aRequestCode, final int aResultCode, 
        final Intent aData) {
    geoDataSender.processOnActivityResult(aRequestCode, aResultCode, 
            new IntentWrapper(aData));
}

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

Но когда я нажимаю кнопку питания (экран отключается),onActivityResult не вызывается вообще. Когда я снова нажимаю кнопку питания,onActivityResult выполняется столько раз, сколькоINTERVAL прошло с тех пор, как я выключил телефон. Если я выключил телефон для1 * INTERVAL миллисекунды, он будет срабатывать один раз. Если я выключил телефон для2 * INTERVAL миллисекунды, будет срабатывать дважды и т. д.

Примечание. Под «выключением» я подразумеваю короткое нажатие кнопки питания (телефон все еще «живет» и реагирует, например, на входящие SMS).

Как я должен изменить кодstartSavingGeoData для того, чтобы методonActivityResult исполняться каждыйINTERVAL миллисекунды, даже когда телефон спит?

Обновление 2 (18.08.2013 19:29 мск): ниalarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 0, INTERVAL, pendingIntent)ниalarmManager.setRepeating(AlarmManager.RTC_WAKEUP, INTERVAL, INTERVAL, pendingIntent) решил проблему.

Ответы на вопрос(1)

Ваш ответ на вопрос