funktionsweise alarmmanager (?)

  • Antworten:53
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 62

04.11.2012 16:00:08 via Website

Hallo an alle,
kurz vor dem abschluss eines grösseren projektes habe ich eine letzte frage.

ich habe eine methode (nennen wir sie keks()) und diese methode soll jeden Tag um z.b 16.00 starten.
ich habe mich im internet etwas informiert,bin aber nur auf extrem komplizierte lösungen gestossen.

wenn ich (pseudocode) schreibe:

public ... keks(){

alarmmanager.(starteJedenTagUm16:00);

doSomething;

}

..dann hieße das,dass er in die methode geht den befehl(alarm) ausführt und dann etwas tut und dann ist die methode abgeschlossen (wenn meine logik stimmt);

Fragen:
1. wie implementiere ich einen (?)Alarmmanager der jeden Tag zu einer bestimmten uhrzeit startet.
2.wie schaffe ich es dass dieser immer wieder aufgerufen wird und die app jedesmal im Hintergrund startet
3. geht es dass ich eine methode aus einer klasse starten kann ohne,dass die ganze App für den benutzer sichtbar geladen wird

vielen dank im voraus :D

Antworten
  • Forum-Beiträge: 287

04.11.2012 19:14:56 via Website

Ganz ist mir nicht klar was Du meinst. Versuche mal kurz zu skizzieren:

Du erzeugt einen BroadcastReceiver:

public class TimerAlarmReceiver extends BroadcastReceiver
{
@Override public void onReceive(Context context, Intent intent)
{
// Hier rein schreiben, was gemacht werden soll.
}
}

Dann registrierst Du einen Alarm für diesen Receiver
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent AlarmIndent2 = new Intent(getAppContext(), TimerAlarmReceiver.class);
PendingIntent AlarmPendIndent2 = PendingIntent
.getBroadcast(getAppContext(), 192837, AlarmIndent2, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), AlarmPendIndent2);

So läuft es bei mir.

Hab allerdings nocht nicht ausprobiert, was passiert wenn ich damit keine Activity öffne.
Ich denke die Application.class immer wird erzeugt. Ob die Lauch-Activity automatisch mit geöffnet wird weiß ich nicht.
Mal ausprobieren....

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

04.11.2012 20:11:44 via Website

Manifest nicht vergessen (android.intent.action.BOOT_COMPLETED).

Diese Art BroadcastReceiver schreibst Du dann nicht als InnerClass in einer Activity sondern als eigenständige Klasse. Es ginge auch als InnerClass, dann musst Du aber mit dem '$' Zeichen beim receiver Tag im Manifest arbeiten.

In Deinem BroadcastReceiver kannst Du dann machen was Du willst - dazu braucht es keine Activity (es sein denn es soll etwas ausgegeben werden).

1<receiver
2 android:exported="false"
3 android:name="MyBroadcastReceiver" >
4 <intent-filter>
5 <action
6 android:name="android.intent.action.BOOT_COMPLETED" />
7 </intent-filter>
8 </receiver>

Antworten
  • Forum-Beiträge: 62

04.11.2012 21:30:53 via Website

Wo in deinem Quelltext wird dann eigentlich die zeit übergeben wann er einen Alarm durchführt ???

Antworten
  • Forum-Beiträge: 287

05.11.2012 10:18:26 via Website

NewAndroidGuy
Wo in deinem Quelltext wird dann eigentlich die zeit übergeben wann er einen Alarm durchführt ???

Das sind nur einige Zeilen aus meinem Code. Die Time erhält Du aus einem Calendar bei dem du die Zeit incl. Datum richtig setzt.
Schauen in der java doku für Calerdar nach.

Calendar time = Calendar.getInstance();
time.add(Calendar.MILLISECOND, (int) ms); /// oder explizit auf 16:00 setzen
am.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), AlarmPendIndent2);

Die Bemerkung von Harald ist sehr wichtig. Du must den Receiver in eine eigene Klasse packen und Android bekannt geben.
Hatte zuerst auch mit ein wenig anderem Code, einen Receiver lokal erzeugt. Damit funktionierte es aber nur, wenn die App auch lief.
Du muß also einen Receiver praktisch unabhängig von dem Zustand deiner App zu verfügung stellen.

Berichte mal wie es läuft, ob deine Receiver im Hintergrund läuft ohen den Mainscreen deiner App zu starten.
Brauche sowas auch die nächsten Tage.

— geändert am 05.11.2012 10:22:46

Antworten
  • Forum-Beiträge: 62

05.11.2012 15:43:48 via Website

Danke werde es in den nächsten Tagen in meine App einbauen (die wird genial) und dann mal berichten wie das so läuft.

Antworten
  • Forum-Beiträge: 62

05.11.2012 16:04:07 via Website

okay ich bin noch nicht ganz bei der sache:

1. ich hab gelesen es gibt einen reciever, der etwas macht wenn das datum am handy gechanged wurde. sagen wir das ist sowas wie ein listener.
gibt es nicht auch einen listener der immer um 16 was macht....

Bei dir andreas ist das so,dass ich aus meinen quelltext sage : wache in so vielen millisekunden auf -ist doch so,oder-.
das hieße dann,dass ich, wenn ich immer um 16h starten will gucken muss:

aktuelle zeit: 15:30:12 hh.mm.ss
zeit zum aufwachen : 16:00:00 """""""""""
macht also 29:48 mm.ss
-> das ganze muss ich dann noch in millisekunden konvertieren und dann über geben -> int convertiert

calendar c = c... .getinst....
c.add(milli.... .(int convertiert) )

ist das so weit korrekt ???

was passiert wenn danach die app geschlossen wird läuft der broadcast "rechner" auch dann noch weiter ???
oder wird der dadurch abgebrochen ??

— geändert am 05.11.2012 16:05:52

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

05.11.2012 16:45:50 via Website

Du musst nach dem Setzen des AlarmManagers überhaupt nichts machen. Du sagst dem System in wie viel Millisekunden es Dich wecken soll. Danach kümmerst Du Dich nicht weiter darum. Pünktlich zur vereinbarten Zeit trudelt im onReceive() Deines BroadcastReceivers eine Mitteilung ein. Was Du damit machst ist Dein Ding.

Ein BroadcastReceiver der im Manifest eingetragen ist und die richtigen Permissions hat (siehe meinen Post oben) läuft auch ohne das die zugehörige App gestartet sein muss - er ist auch nach einem System-Neustart noch aktiv (deshalb der BOOT_COMPLETED).

— geändert am 05.11.2012 16:52:17

Antworten
  • Forum-Beiträge: 287

05.11.2012 16:47:32 via Website

Wollte jetzt nicht den fertigen Code für Dich entwickeln sondern nur zeigen wo es lang geht. Must selber mal in der SDK Hilfe schauen. "AlarmMananger"

Im Calendar kannst Du auch die Zeit expizit setzen und muß nicht so umständlich Millisekunden addieren. Hab einfach so den code gepostet wie ich ihne verwenden. Suche im Netz "Java Calendar". Da findes Du genug Infos.
Mit am.set setzt du die ABSOLUTE Zeit, kein Intervall.
Nachdem der eine Alarm gefeuert hat muß Du natürlich den nächsten Alarm setzen. Sicherheitshabler mach ich vorher immer noch: am.cancel(AlarmPendIndent2);

Wie ich schon geschrieben hatte, wenn du es genauso machts wie ich läuft der Alarm unabhängig von dem Zustand deiner App (gestartet oder auch nicht).

Da bin ich ja mal gespannt auf Deine geniale App...

Antworten
  • Forum-Beiträge: 62

05.11.2012 18:25:24 via Website

jetzt bin ich ready hab gerade in die klassenbibliothek reingeguckt und system verstanden ready zum einbauen :D

Antworten
  • Forum-Beiträge: 62

05.11.2012 21:04:19 via Website

irgendwie hab ich es nicht geschafft oder ich bin primär doof

1. manifest geändert
:
:
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".GridstundenplanActivity"
android:label="@string/app_name"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver
android:name="MyBroadcastReceiver"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>

</manifest>

2. Alarm abgesendet in einer minute ab jetzt:
public void Broadcaster(){

Calendar time = new GregorianCalendar();
time.getInstance();
//time.add(Calendar.DAY_OF_WEEK_IN_MONTH, +1);
//time.set(Calendar.HOUR_OF_DAY, 19);
//time.set(Calendar.MINUTE,50);
time.add(Calendar.MINUTE, +1);
System.out.println(time);

AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent AlarmIndent2 = new Intent(getApplicationContext(), GridstundenplanActivity.class);
PendingIntent AlarmPendIndent2 = PendingIntent.getBroadcast(getApplicationContext(), 192837, AlarmIndent2, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), AlarmPendIndent2);



}

3. Recieve class erstellt:
:
:
public class TimerAlarmReceiver extends BroadcastReceiver {

public void onReceive(Context context, Intent arg1) {
System.out.println("RECIEVED");
Toast.makeText(context,("lsustsgd"),Toast.LENGTH_LONG).show();
}}

aber nichts passiert !!!

Antworten
  • Forum-Beiträge: 62

05.11.2012 22:20:23 via Website

und ich wusste das da der fehler liegt lalala

kopf gegen die wand und weg mit dem

android:name="TimerAlarmReceiver" <---- habs auf die receiver class gestellt aber trotzdem kommt der system.out.print nicht

kann es sein das hier auch ein problem liegt: <action android:name="android.intent.action.BOOT_COMPLETED" />

— geändert am 05.11.2012 22:43:29

Antworten
  • Forum-Beiträge: 62

05.11.2012 22:56:00 via Website

Alarmmanager funzt:

if (am==null){System.out.println("nicht verschickt");}

bzw ist declariert, ich weiß nicht ob in der logcat ne nachricht kommt, bei mir nicht also nicht verschickt ???

Antworten