startet setRepeating inexact?

  • Antworten:17
fileerror
  • Forum-Beiträge: 116

18.12.2014, 08:43:24 via App

Der Titel sagt es schon, wenm ich meinen AlarmManager mit setExact starte passt alles. Mit setRepeating verzögert sich der Start mal mehr mal weniger (Die Wiederholung hab ich nicht getestet aber das spielt erstmal keine Rolle) . Ist das normal? Wenn ich jetzt z.B. ne Wecker-App machen will, dann muss der Alarm doch genau sein und jeden Tag genau wiederholt werden. Oder muss man in diesem Fall setExact nutzen und jeden Tag den AM neu setzen lassen? Danke schonmal.

Gruß fileerror

Antworten
fileerror
  • Forum-Beiträge: 116

18.12.2014, 10:06:30 via Website

Danke da steht es ja.
Und wie kann man das lösen (z. B. für Wecker) Über einen kleinen Denkanstoß würde ich mich freuen.

Antworten
fileerror
  • Forum-Beiträge: 116

18.12.2014, 14:27:19 via Website

Ok eigentlich brauch ich ja nur einen Service der einmal am Tag (Nacht) prüft, welcher Alarm noch aktiv ist und die abgelaufenen neu setzt. Nur woher bekommt der Service die Zeiten? Man kann ja damit nicht auf die sharedPrefs der MainActivity zugreifen denke ich. Kann der Thread vielleicht direkt auf die Variablen der MainActivity zugeifen, wenn ich sie auf public setze?

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

18.12.2014, 15:27:37 via Website

Der Service kann auf SharedPrefs zugreifen (zumindest habe ich das schonmal mit einem IntentService gemacht, vielleicht verstehe ich es aber auch nicht richtig).

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

18.12.2014, 23:04:28 via Website

Lars F.

Der Service kann auf SharedPrefs zugreifen (zumindest habe ich das schonmal mit einem IntentService gemacht, vielleicht verstehe ich es aber auch nicht richtig).

SharedPrefs können von jeder Komponente einer App gemeinsam genutzt werden ... darum auch der Name :)

Antworten
pepperonas
  • Forum-Beiträge: 434

20.12.2014, 01:58:04 via Website

fileerror

Man kann ja damit nicht auf die sharedPrefs der MainActivity zugreifen denke ich.

Doch.

Kann der Thread vielleicht direkt auf die Variablen der MainActivity zugeifen, wenn ich sie auf public setze?

Nein, das geht nicht ohne Weiteres (erst müsstest du sie als static deklarieren) und selbst wenn, wäre es eine ganz schlechte Idee.

Die Frage ist nur ob du es wirklich brauchst... Android kümmert sich schon um deinen Alarm, wenn du ihn richtig einstellst. Die Shared Prefs brauchst du dazu nicht zwangsläufig - außer du willst sowas wie ein Einstellungsmenü anbieten, dann bietet es sich natürlich an. Aber aus der MainActivity als solchen reicht ein Aufruf deines Services mit dem du einfach ein paar Werte übergibst... (so wie du es bereits gemacht hast, wenn ich dich richtig verstanden habe)

siehe hier

Open Source

Antworten
fileerror
  • Forum-Beiträge: 116

20.12.2014, 10:28:11 via Website

Ja es funktioniert jetzt schon halbwegs. Ich möchte es halt so machen, dass ein Service irgendwann um 3 oder so überprüft, welcher Alarm noch aktiv ist und ggfs. neu setzt. Habe das schon im Kopf. Und ja, ich habe in der Main ein Menü, in dem ich alle Alarme ändern kann. Hab auch herausgefunden, wie das mit den Sharedprefs funktioniert. Es kommt darauf an, wie man sie anlegt, ob nur die Activity, oder die ganze App darauf zugreifen kann.

Antworten
fileerror
  • Forum-Beiträge: 116

20.12.2014, 11:50:26 via App

Ich poste es dann, jedenfalls musste ich da was ändern zu default.. weiß nimmer.
Wenn du einmal dabei bist 3 kleine Fragen zu meinem besseren Verständnis:

  1. Wenn ein Service nur was abarbeitet und dann fertig ist, muss er dann beendet werden? (stopSelf()) oder beendet er sich dann automatisch?

  2. Wann brauch man eigentlich einen Service? Wenn ich jetzt beim Alarm nur das Handy stummschalten will, kann man da z.B. den Code direkt in den BroadcastReceiver (onReceive) schreiben?

  3. Hab mal gelesen man sollte bei onPause die SharedPrefs speichern und bei onResume laden. Das hatte ich auch so gemacht und ging auch. Nur: jedes mal wenn ich das Handy drehe wird beides ausgeführt und das Schlimmste: onResume ist schneller als onPause! D.h. nach dem drehen ist der Vorzustand wieder hergestellt und auch noch gespeichert. Sehr merkwürdig. Und warum wird es beim Drehen überhaupt ausgeführt?

Bin mal sehr gespannt auf die Antworten. ;)

— geändert am 20.12.2014, 11:51:08

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

20.12.2014, 12:05:03 via Website

1) Das hängt auch davon ab wie du deinen Service aufgebaut hast, siehe: http://developer.android.com/reference/android/app/Service.html#START_NOT_STICKY

2) ja, sehr kurze Operationen rechtfertigen den Aufwand eines Service nicht wirklich

3) "onResume ist schneller als onPause" ist nach dem definierten Lifecycle von Activity/Fragment unmöglich.
Wenn es in Android tatsächlich einen solchen Klopper gäbe, wäre er nach 5 Android Generationen garantiert aufgefallen. Bei Google sitzen ja schon 1-2 schlaue Leute.
So leid es mir tut, der Fehler muss in Deinem Code liegen.

Antworten
fileerror
  • Forum-Beiträge: 116

20.12.2014, 12:40:34 via App

Ok also danke für die schnellen Antworten.

zu 1. Muss ich dann daheim lesen!

zu 2. Geht das so weit, dass der BR die SharedPrefs lesen und SICH SELBST neue Alarme aus den Daten setzen könnte?

zu 3. Klingt plausibel. Muss ich nochmal testen, was da los ist.

Antworten
fileerror
  • Forum-Beiträge: 116

21.12.2014, 05:40:32 via Website

Also bei den SharedPrefs musste ich das:

SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);

in das:

SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);

ändern, um sie vom Service nutzen zu können.

Gurß fileerror

Antworten
fileerror
  • Forum-Beiträge: 116

28.12.2014, 10:54:48 via Website

Hallo, ich habe nochmal eine Frage dazu: Also ich benutze jetzt setExact und das funktioniert! Nur setExact wurde erst ab API19 eingeführt. Wenn ich jetzt meine App zu API 14 kompatibel machen will, wie gehe ich da vor? Ich schätze mal ich muss man beim Start der App die API checken und es dann so in der Art:

if(API < 19)
set....
else
setExact...

lösen. Ist das so sinnvoll, oder gibt es da einen besseren Weg? Und Eclipse meldet ja auch einen Fehler, wenn ich setExact nutze, bei minSDK14 im Manifest. Wie checkt man eigentlich die API?

Fragen über Fragen. Danke schon mal.

Gruß fileerror

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

28.12.2014, 11:50:33 via Website

Musst Du wohl so machen, wenn Du exakte Alarme brauchst.

Wenn Du die passende if-Abfrage hast und sichergestellt ist, dass der Code nur auf Android Geräten mit passender Version ausgeführt wird,
kannst Du mit @Suppress annotations die Warnung unterdrücken.
Aber Vorsicht, die gilt je nach Position für die ganze Methode oder Klasse, also wenn Du dann wieder etwas machst, was in Deinem API Level nicht funzt, wird der Fehler ignoriert.

Antworten
fileerror
  • Forum-Beiträge: 116

28.12.2014, 12:39:58 via Website

Da der User die Zeiten selbst einstellen kann, würde er sicher am Programmierer zweifeln, wenn es dann nie zum eingestellten Zeitpunkt auslöst. Deswegen setExact ;)

— geändert am 28.12.2014, 12:44:00

Antworten
fileerror
  • Forum-Beiträge: 116

05.01.2015, 12:23:53 via Website

Ich werd noch verrückt. Bis vor kurzem hat dieser Code wunderbar funktioniert. Jetzt gehen plötzlich alle Alarme auf einmal los.
Wenn ich mit dem Debugger die Werte auslese setzt es irgendwo zwischendrin die Zeit auf November 2014. Ich finde den Fehler einfach nicht,
vor allem, weil ich am Code nichts geändert habe. Vielleicht könnt ihr ja mal drüber gucken und mir sagen, was ich ändern muss ;).
Danke schon mal.

Calendar calendarActual = Calendar.getInstance();
calendarActual.setTimeInMillis(System.currentTimeMillis());

    for (int i = 0; i < 7; i++)
        if (tBChecked[i]) {
            Calendar calendarStart = Calendar.getInstance();
            calendarStart.setTimeInMillis(System.currentTimeMillis());
            calendarStart.set(Calendar.HOUR_OF_DAY, startHour[i]);
            calendarStart.set(Calendar.MINUTE, startMinute[i]);
            calendarStart.set(Calendar.DAY_OF_WEEK, i + 1);
            calendarStart.set(Calendar.SECOND, 0);

            Calendar calendarWarning = Calendar.getInstance();
            calendarWarning.setTimeInMillis(calendarStart.getTimeInMillis() - (30 * 1000));  

            Calendar calendarStop = Calendar.getInstance();
            calendarStop.setTimeInMillis(System.currentTimeMillis());
            calendarStop.set(Calendar.HOUR_OF_DAY, stopHour[i]);
            calendarStop.set(Calendar.MINUTE, stopMinute[i]);
            calendarStop.set(Calendar.DAY_OF_WEEK, i + 1);
            calendarStop.set(Calendar.SECOND, 0);


            if (calendarStart.get(Calendar.DAY_OF_WEEK) < calendarActual
                    .get(Calendar.DAY_OF_WEEK)) {
                calendarStart.add(Calendar.WEEK_OF_YEAR, 1);
                calendarWarning.add(Calendar.WEEK_OF_YEAR, 1);
                calendarStop.add(Calendar.WEEK_OF_YEAR, 1);
            }

— geändert am 05.01.2015, 12:24:31

Antworten