Как постоянно отслеживать местоположение мобильного телефона 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)
решил проблему.