Wie kann ich den Standort eines Android-Handys kontinuierlich verfolgen?

Ich muss eine App schreiben, die alle 5 Minuten den aktuellen Standort des Mobiltelefons ermittelt (unter Verwendung aller kostenlosen, verfügbaren Standortanbieter) und an einen Server sendet.

Wenn ein Standortanbieter beim Start der Anwendung nicht funktioniert, aber später verfügbar wird, sollte die Anwendung auch ihre Standortdaten verarbeiten.

Dazu habe ich folgende Klasse implementiert. In einer meiner Aktivitäten erstelle ich eine Instanz davon und rufe sie aufstartTrackingUpdates Methode.locationChangeHandler erledigt die Verarbeitung von Standortdaten.

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) {
    }
}

Ich habe die Anwendung erstellt und auf meinem Mobiltelefon installiert. Dann, am Morgen, nahm ich mein Handy, ging zur Arbeit und ging dann zurück nach Hause. Zu Hause überprüfte ich die Ergebnisse einer Tagesarbeit der Anwendung und fand nur einen Datensatz in der Datenbank.

Unter der Voraussetzung, dass der Rest des Systems (Übertragung der Standortdaten an den Server, Speichern in der Datenbank) ordnungsgemäß funktioniert, muss der Standortverfolgungscode ein Problem aufweisen (onLocationChanged wurde nicht aufgerufen, obwohl ich meinen Standort mehrmals geändert habe).

Was ist los mit meinem Code (wie soll ich ihn ändern, damit dieonLocationChanged angerufen werden, wenn sich der Standort des Telefons um mehr alsMIN_DISTANCE_CHANGE_FOR_UPDATES Meter nach einem der locatin Anbieter)?

Update 1 (18.08.2013 13:59 MSK):

Ich habe meinen Code entsprechend geändertmsh Empfehlungen. Ich starte den Timer mit folgendem Code:

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

In demactivity Ich habe folgenden Timer-Event-Handler gesetzt:

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

Wenn das Telefon eingeschaltet ist, funktioniert alles wie erwartet -onActivityResult wird einmal in ausgeführtINTERVAL Millisekunden.

Aber wenn ich den Netzschalter drücke (Bildschirm wird deaktiviert),onActivityResult wird überhaupt nicht aufgerufen. Wenn ich den Netzschalter erneut drücke,onActivityResult wird so oft ausgeführt, wieINTERVAL ist vergangen, seit ich das Telefon ausgeschaltet habe. Wenn ich das Telefon für ausgeschaltet habe1 * INTERVAL Millisekunden, es wird einmal ausgelöst. Wenn ich das Telefon für ausgeschaltet habe2 * INTERVAL Millisekunden, es wird zweimal ausgelöst usw.

Hinweis: Mit "Ausschalten" meine ich ein kurzes Drücken des Netzschalters (das Telefon "lebt" weiterhin und reagiert beispielsweise auf eingehende SMS).

Wie soll ich den Code von ändern?startSavingGeoData in Ordnung für die MethodeonActivityResult ausgeführt werdenINTERVAL Millisekunden, auch wenn das Telefon schläft?

Update 2 (18.08.2013 19:29 MSK): WederalarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 0, INTERVAL, pendingIntent), NochalarmManager.setRepeating(AlarmManager.RTC_WAKEUP, INTERVAL, INTERVAL, pendingIntent) Problem gelöst.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage