2012-09-24 6 views
5

Ich schreibe eine Android-Anwendung, wo der Benutzer mehrere Aktien zu beobachten und wird benachrichtigt werden, wenn eine vordefinierte Alarmbedingung übereinstimmt. Die Bestandsdaten werden in 5 Objekten einer benutzerdefinierten Parcelable-Klasse "alert" (ein Objekt pro Bestand und Bedingung) gespeichert. Die periodische Datenaktualisierung erfolgt über einen von einem AlarmManager gestarteten Dienst. Die Alert-Objekte werden an den Service übergeben, indem sie in den Intent übernommen werden, der in den PendingIntent des AlarmManagers eingefügt wird.Wie werden die Daten aktualisiert, die mit Absicht an einen Dienst gesendet werden, wenn der Dienst vom Alarmmanager gestartet wird?

Intent intent = new Intent(this, UpdateService.class); 
    Bundle b = new Bundle(); 
    saveAlertsToBundle(b);  
    intent.putExtras(b); 
    intent.setData(Uri.parse("updateManager")); 
    PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); 

    // 1min intervall 
    long intervall = DateUtils.MINUTE_IN_MILLIS * 1; 
    // time of first start 
    long firstStartDelay = DateUtils.SECOND_IN_MILLIS * 30; 
    long firstStart = System.currentTimeMillis() + firstStartDelay; 

    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
    // kill running 
    am.cancel(pendIntent); 
    //start new 
    am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent); 

Mein Problem ist:

Wenn der Dienst zum ersten Mal starten, wenn nur ein Objekt der Benachrichtigung an den Service funktioniert alles einwandfrei geführt ist. Sobald mehr Alert-Objekte vorhanden sind, müssen sie auch an den Service übergeben werden, aber dies funktioniert nicht mit dem obigen Code. Der Service erhält den aktualisierten Intent nicht mit den zusätzlichen Alert-Objekten, sondern nur mit dem ersten Alert-Objekt. Der obige Code erstellt korrekt eine Absicht, die das zusätzliche Warnmeldungsobjekt enthält, sie gelangen jedoch nie zum Dienst.

Also meine Frage ist, wie die aktualisierte Absicht an den bereits laufenden AlarmManager übergeben wird.

Ich habe bereits versucht, den AlarmManager (die Zeile am // kill running comment) zu stoppen und neu zu starten, aber das funktioniert nicht. Vielleicht wegen der Absicht, nicht dieselben Alarmobjekte zu halten, wie zu der Zeit, als er erschaffen wurde? Ich habe versucht, dies zu beheben, indem ich ein uri in den Datenteil der Absicht setzte, aber das half auch nicht.

Danke für Hilfe.

Antwort

2

Ihr Problem ist die Art und Weise PendingIntent funktioniert. Das System verwaltet einen Pool von PengingIntent s. Wenn Ihr Code tut.

PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); 

Dies veranlasst das System für eine PendingIntent zu suchen, die die Parameter entspricht, die Sie in (in diesem Fall bestanden haben, Ihre Intent verwendet jedoch die Matching-Algorithmus, der PendingIntent vergleicht nur bestimmte Felder von Intent zu bestimmen, ob es das ist, das Sie suchen.Vor allem, es nicht vergleichen Extras.So bedeutet dies, nachdem Sie die erste PendingIntent erstellt haben, wird der Anruf an PendingIntent.getService() wird immer die gleichen PendingIntent aus der Pool (und nicht einen neuen erstellen, was Sie wollen)

Um das Gespräch zu PendingIntent.getService() erstellen Sie ein neues PendingIntent jedes Mal, wenn Sie es nennen zu machen, versuchen die Parameter machen Sie den Anruf übergeben einzigartig, wie folgt aus: zu

int requestCode = (int) System.currentTimeMillis(); // Create unique request code 
PendingIntent pendIntent = PendingIntent.getService(this, requestCode, intent, 0); 

Da requestCode für jeden Anruf wird anders sein PendingIntent.getService(), sollte dies Ihr Problem lösen.

EDIT Basierend auf OP Kommentare unten

Sie möchten die bestehenden Alarm löschen und eine neue mit neuen Daten erstellen. In diesem Fall müssen Sie keine eindeutigen Bezeichner verwenden, da Sie nur einen einzigen PendingIntent im Pool haben möchten. Aber Sie möchten die Daten dafür ändern.Versuchen Sie dies:

+0

Vielen Dank für Ihre Hilfe, löste das Problem, sondern schuf eine neue. Die zusätzlichen Alarmobjekte werden an den Dienst übergeben, aber als zusätzliche AlarmManager-gesteuerte Dienste laufen die bereits laufenden AlarmManager weiter. Daher erhöht sich die Anzahl der AlarmManager jedes Mal, wenn ich ein Alarmobjekt hinzufüge. Das heißt, ich habe einen für ein Alarmobjekt, einen für zwei, einen für drei, usw. Ich denke, es wäre besser, wenn es nur einen mit der aktuellen Anzahl vorhandener Alarme gäbe, also muss ich den alten AlarmManager anhalten. Die Dienste werden mit einem Aufruf von stopSelf() beendet. – user1695117

+0

OK. Ich war mir nicht sicher, was genau du machen wolltest. Aufgrund dieses Kommentars klingt es so, als ob Sie den bestehenden Alarm abbrechen und einen neuen mit den neuen Parametern erstellen möchten. Ich werde meine Antwort dafür bearbeiten. –

+0

Das hat perfekt funktioniert. Alles, was mir fehlte, war die richtige Flagge. Danke für Ihre Hilfe. – user1695117

Verwandte Themen