Intent mit Zeitverzögerung ?

znieh99

znieh99

Fortgeschrittenes Mitglied
12
Hallo Forum,
ist es möglich einen Intent abzusetzen, der erst nach einer zu definierenden Zeit aktiv wird ?
lg heinz
 
Ja schon nur nicht so einfach.
Benutze dazu den alarmmanager mit dem du einen pendingintent in dem du einen intent packst verschickst.
 
Hallo jogimuc,
habe mich umgesehen und eine Beispiel gefunden welches fehlerfrei durchlaufen wird, aber keine Aktion in meinem onReseive auslöst. Ich nehme an es liegt an den Intent-Filter in der Manifest. Oder liege ich da daneben?
lg Heinz
Code:
public void startAlarm(Context context) {
        Intent intent = new Intent(context, MeinBroadcastReceiver.class);
        PendingIntent sender = PendingIntent.getService(context, 0, intent, 0);
        AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000 * 5, 1000 * 5, sender);

    }
 
Ja wenn du willst das dein Receiver den penting empfängt brauchst du einen intentfilter.
Aber dein penting ist so auch nicht richtig.

mAlarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
mIntent = new Intent();
mIntent.setAction("UPDATE");
mPendingIntent = PendingIntent.getBroadcast(context, 0, mIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis() + 1000*5);
mAlarmManager.setRepeating( AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000 * 5, 1000 * 5, mPendingIntent);


<receiver android:name=".MeinBroadcastReceiver">
<intent-filter>
<action android:name="UPDATE"></action>
</intent-filter>

willst du wirklich das der intent immer wiederholt wird? Bis du den Alarm beendest?
Auch musstest du dir die aktuelle Laufzeit des Systems in millisec holen unfrei e Verzögerung dazu addieren wenn die Verzögerung in der Vergangenheit liegt wird der pending sofort ausgelöst .
 
  • Danke
Reaktionen: znieh99
jogimuc schrieb:
willst du wirklich das der intent immer wiederholt wird? Bis du den Alarm beendest?
Auch musstest du dir die aktuelle Laufzeit des Systems in millisec holen unfrei e Verzögerung dazu addieren wenn die Verzögerung in der Vergangenheit liegt wird der pending sofort ausgelöst .
Nun, ich benötige eine periodische Abfrage des Ladezustand vom BatteryManager - um z.B. bei 30% Ladekapazität eine Meldung auszugeben. Der Intervall dieser Abfrage (z.B. 15 Min.) soll individuell eingestellt werden können. Ich möchte dafür den BroadcastReceiver verwenden, da er nicht gekillt wird wenn die Activity gekillt wird.
Und herzlichen Dank für dein Beispiel das ich nun studieren werde,
lg heinz
 
@jogimuc
Uff, ich habe es geschafft - zumindest im Emulator!
Ich habe die letzte Zeile auch noch wie folgt angepasst:
Code:
calendar.setTimeInMillis(System.currentTimeMillis() + 1000*5);
 mAlarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), mPendingIntent);
Zum besseren Verständnis habe ich die Ablaufstruktur für die App erstellt wie sie sich nun darstellt:
Ablaufstruktur.PNG

Eine Frage bleibt noch offen: Kann ich den BroadcastReceiver mit this.finalize() auch beenden?
lg heinz
 
  • Danke
Reaktionen: jogimuc
Eine Frage bleibt noch offen: Kann ich den BroadcastReceiver mit this.finalize() auch beenden?

Kann ich dir nicht sagen. eigentlich wird die Methode selber vom Garbage Collector aufgerufen bevor das Objekt beendet wird.

Habe ich noch nie gemacht macht auch keinen richtigen sinn.

Wenn du die Abfrage nicht mehr willst beende den Alarmmanager.


Ich denke solange der IntentFidler aktiv ist wird auch der Provider aktiv bleiben ob er nun im Speicher ist oder nicht. Wenn der Filter einen Passenden Intent findet wird er ihn starten, aufrufen.
 
  • Danke
Reaktionen: znieh99
znieh99 schrieb:

Eine Frage bleibt noch offen: Kann ich den BroadcastReceiver mit this.finalize() auch beenden?
lg heinz


Nein, solange du den im Mainfest deklarierst, wird der vom System verwaltet.

Sonst muss du LocalBroadcastManager verwenden. Der kann auch Broadcastreceiver wieder abmelden.
 
  • Danke
Reaktionen: jogimuc und znieh99
znieh99 schrieb:
Hallo jogimuc,
habe mich umgesehen und eine Beispiel gefunden welches fehlerfrei durchlaufen wird, aber keine Aktion in meinem onReseive auslöst. Ich nehme an es liegt an den Intent-Filter in der Manifest. Oder liege ich da daneben?
lg Heinz
Code:
public void startAlarm(Context context) {
        Intent intent = new Intent(context, MeinBroadcastReceiver.class);
        PendingIntent sender = PendingIntent.getService(context, 0, intent, 0);
        AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000 * 5, 1000 * 5, sender);

    }

Nur zu Info, ich weiß nicht was du geändert hast, aber du musst für einen Receiver auch PendingIntent.getReceiver verwenden, nicht PendingIntent.getService.
 
Hi Deek
was ich da geändert habe kanste dir in meinen Post anschauen. und er hat es auch gelöst.
Ich habe dem Intent eine Action gegeben und genau auf die Action reagiert der Intentfilter wenn er als Broadcast verschickt wird.

Lese doch bitte den ganzen Thread.

mIntent.setAction("UPDATE");
mPendingIntent = PendingIntent.getBroadcast(context, 0, mIntent, 0);
 
Zuletzt bearbeitet:
Das ist die funktionierende Methode:
Code:
 private void startAlarm(final Context context) {
         AlarmManager mAlarmManager;
         Intent mIntent;
         PendingIntent mPendingIntent;

        mAlarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
        mIntent = new Intent();
        mIntent.setAction("UPDATE");
        mPendingIntent = PendingIntent.getBroadcast(context, 0, mIntent, 0);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis() + 1000*5);
        mAlarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), mPendingIntent);

    }
 
Ja ist genau das was ich gepostet habe. Ob es nun AlarmManager.RTC_WAKEUP oder AlarmManager.ELAPSED_REALTIME_WAKEUP ist spielt erst mal keine Rolle . Mit Rtc geht das mit dem Kalender besser um die Start Verzögerung fest zulegen . :)

Habe es nur so gelassen weil dein erstes Beispiel auch drauf auf baute, dachte du wolltest es so haben.

verstehe @deek nicht. Klar kann man es auch mit PendingIntent.getReceiver machen .

Aber er wollte ja wissen was du verändert hast das hätte er auch in meinen Post gesehen.


lesen hilft manchmal.
 
Ich möchte auch noch anmerken das du nicht vergessen darfst das ganze neu zu timen wenn du das Handy bootest, sich die Uhr ändert usw.
Hab die letzten 3 Monate selbst zeit gesteuerte notifications verwendet, ein * * * * :D

Außerdem gibt es ab Android O Einschränkungen bei impliziten Broadcast Receivern.

Wollte ich nur mal hier angemerkt haben =)

lg. Dagobert
 
  • Danke
Reaktionen: markus.tullius
@DagobertDokate
Danke für den Hinweis. Aber hier kommt es nicht auf exates Timing an. Die Aufgabe wird sein, "schau mal alle 15 - 20 Min nach ob der Akku schon eine Ladeuntergrenze erreicht hat und melde mir das".
lg heinz
 
Ja das hab ich mitbekommen. Aber wenn du das nicht behandelst sagt dir das dein Handy nur solange bis es abstürzt^^ oder auch gewollt neugestartet wird^^
 
  • Danke
Reaktionen: markus.tullius
DagobertDokate schrieb:
Ja das hab ich mitbekommen. Aber wenn du das nicht behandelst sagt dir das dein Handy nur solange bis es abstürzt^^ oder auch gewollt neugestartet wird^^
Ok, dann muss ich es neu starten. Oder gibt es da andere Möglichkeiten?
 
Hi
Ja richtig zumindest den Neustart des Handys also
ACTION_BOOT_COMPLETED solltest du abfangen und den Alarmmanager neu starten.

Aber wie so machst du eigentlich so ein Aufwand du kannst doch auch die Action
ACTION_BATTERY_LOW abfangen und auswerten.
Wann das System bzw bei welchem Prozentwert der verschickt wird musst du testen.
Vielleicht reicht dir das auch schon.

>Ok, dann muss ich es neu starten. Oder gibt es da andere Möglichkeiten?
ja auch über einen Broadcast Resiver der auf die Action "ACTION_BOOT_COMPLETED" wartet.
[doublepost=1532442678,1532442339][/doublepost]@DagobertDokate
>Außerdem gibt es ab Android O Einschränkungen bei impliziten Broadcast Receivern.

welche sind das? kannst du darüber berichten.
 
Zuletzt bearbeitet:
jogimuc schrieb:
Aber wie so machst du eigentlich so ein Aufwand du kannst doch auch die Action
ACTION_BATTERY_LOW abfangen und auswerten.
Nun ich will nicht warte bis mir das System sagt das ich laden soll sondern bereits bei 30 - 35% laden und das Laden beenden bei 65 - 70%.
 
Ok dann bleibt dir da wohl nichts anderes übrig.

was mir noch an deinen Code aufgefallen ist.

> calendar.setTimeInMillis(System.currentTimeMillis() + 1000*5);
> mAlarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), mPendingIntent);

1000*5 sind nur 5 sec. minimum ist eigentlich 1 min. 1000*60

du wolltest doch eine ständige Wiederholung haben oder?
Nur mit mAlarmManager.set müsstest du den immer wieder neu setzen.

Einfacher ist

mAlarmManager. setRepeating (AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, mPendingIntent);

Somit würde jede Minute ein Intent gesendet.
Übrigens kannste bei dem anfangs wert auch 0 eingeben dann wir der erste Intent gleich gesendet. Das gleich nicht wörtlich nehmen der ALM ist etwas ungenau.
Denn der erste Start liegt somit in der Vergangenheit
mAlarmManager. setRepeating (AlarmManager.RTC_WAKEUP, 0, 1000 * 60, mPendingIntent);
 
@jogimuc
Die 5 Sek. sind nur ein Testwert, in echt werden es 20 Min sein. Das mit ".setRepeating" muss ich mir noch überlegen.
 

Ähnliche Themen

B
Antworten
4
Aufrufe
487
bb321
B
FabianDev
Antworten
5
Aufrufe
555
swa00
swa00
MES
Antworten
10
Aufrufe
819
MES
MES
Zurück
Oben Unten