Service, ist doch kein Service

  • 14 Antworten
  • Neuester Beitrag
Diskutiere Service, ist doch kein Service im Android App Entwicklung im Bereich Betriebssysteme & Apps.
B

Black Rider

Neues Mitglied
Hallo zusammen

Ich will eine App programmieren welche nur im Hintergrund läuft, aber durchgehend.

Natürlich habe ich gegoogelt ;) Meine App hat ein MainAtivity (Blank), diese startet bei OnCreate meinen service und beendet sich dann mit finish().

In meinem Service hat es bis jetzt nichts anderes als eine for Schlaufe, welche alle 2 Sekunden eine neue Notification schmeisst. (Test).


Wenn ich die App starte, öffnet er das Acticvity, startet meinen Service, schliesst sich und der Service fängt an die Informationen in der Schlaufe zu posten. Nach etwa 20 Sekunden hört er dann jedoch einfach auf.
Da ich unter "Allen laufenden Apps" beim Handy (HomeButton lange drücken) meine App auch sehe, gehe ich davon aus, das diese nicht wirklich als Dienst läuft. Wie kriege ich das hin?

Gruss

Black Rider
 
Jaiel

Jaiel

Dauergast
Etwas Code würde helfen und Apps bleiben in der Regel in dieser Liste man muss sie manuell entfernen.

Vllt hast du ein Fehler bei den Notifications gemacht und postest diese ohne Pendingintent sprich ist die Activity tot geht auch keine Notification absetzen
 
Zuletzt bearbeitet:
D

deek

Stammgast
a) Das System kann einen Background Service beenden wann es will.
b1) Du kannst einen Foreground Service (verwendet eine dauerhafte Notification) verwenden, der wird nicht so schnell gekillt (kann aber auch gekillt werden)
b2) Du kannst zwei Services verwenden die sich immer gegenseitig wieder starten wenn einer beendet wurde
c) die onStartCommand Methode des Service sollte terminieren und START_STICKY zurückgeben.
d) Statt einer for Schleife solltest du ein Runnable und einen TimerTask verwenden. Oder einen neuen Thread starten mit einer Schleife. (Aber busy loops sind immer eine schlechte Idee, verwende bitte die Einrichtungen die es im SDK dafür gibt)
e) kein User will alle 2 Sekunden eine Notification
 
Jaiel

Jaiel

Dauergast
b2 kann gefährlich werden...
Warum sollte sein Service nach 20 Sekunden schon gekillt werden?
 
B

Black Rider

Neues Mitglied
Hallo zusammen

Erstmal, danke für die Antworten. Anscheinend ist es nicht so einfach wie ich dachte :/ Aus diesem Grund erzähl ich am besten was ich erreichen will, anstatt mich über Wege zu informieren die eventuell sowieso falsch sind.

Die App ist schlussendlich nur für mich. Sie im Hintergrund laufen und alle paar Minuten meine Position an meinen MySQL Server senden. Zweck von dieser ganzen Sache ist hauptsächlich, das wenn ich beim Biken unterwegs auf die fr*** falle un liegen bleibe, man schnell schauen kann wo ich bin. Wenn mein Handy geklaut wurde, ich schnell guggen kann wo es sein sollte und zudem fände ich es noch interessant ne "Wo war ich im letzten Jahr" Grafik :)

Für einen Teil gibt es sicherlich schon App's (Searchmymobile, etc.etc.). Aber ich dachte eigtl. das sei nicht so schwer und ziemlich fix gemacht, desswegen wollte ich es selber programmieren.

Einfach gesagt: Backgroundworker welcher alle x Minuten kurz die GPS Daten abruft und an meinen MySQL Server sendet. Aber dafür brauche ich einen Service welcher stabil im Hintergrund läuft und nicht einfach vom System, wenn es gerade bock hat, gekillt wird.

Das mit MySQL habe ich im Griff.

Was meint Ihr?

Gruss

Black Rider
 
Jaiel

Jaiel

Dauergast
Also für soetwas wäre der Alarmmangaer sehr geeignet damit hast du kein Overhead auf das nächste Ereignis zu warten.

Hier: https://www.android-hilfe.de/forum/...ication-mit-alarmmanager-anzeigen.690679.html

Das kannst du als Basis nehmen und in onReceive im BroadcastReceiver deine SQL aktualisierung vornehmen anstatt eine Notification abzusetzen (am besten einen Service starten in einem extra thread da android onReceive() nach 10 sekunden killen kann wenn er zu lange braucht).

Du kannst auch den Alarm so einstellen dass er sich wiederholt guck am besten in die API für den Alarmmanager(setInexactRepeating() ist brauchbar dafür)

So sollte es am besten funktionieren meine ich

lg
 
D

deek

Stammgast
bezüglich der 20 Sekunden: Ich weiß es nicht 100%ig, aber ich könnte mir vorstellen, dass ein Service die onStartCommand Methode komplett (also mit Rückgabe) ausführen muss innerhalb einer bestimmten Zeit. Wenn er jetzt die for Schleife direkt in onStartCommand ausführt, kommt diese nie zurück.
BroadcastReceiver werden auch nur eine gewisse Zeit ausgeführt. Da der Service im Main Thread läuft ist das für das System ein Hinweis auf eine ineffiziente Thread Nutzung wenn onStartCommand nicht zurück kommt. Daher kann es gut sein, dass das dann gekillt wird.

Vielleicht hilft das:
https://maps.google.com/locationhistory/b/0

b2 ist nicht gefährlich, aber dämlich. Ich wollte es nur der Vollständigkeit halber erwähnen.
 
Jaiel

Jaiel

Dauergast
Früher kponnte man Android zwingen exakt einen Broadcast loszulassen heute ist es besser man überlässt das dem System

Aber es handelt isch bei ihm ja um "alle paar minuten" da sind 2-3 sekunden spätert wohl kein Problem...und ja man sollte ein Prozess auf einen seperaten Thread vom UI thread laufen lassen. Vor allem bei Prozessen die unbestimmt lange dauern wie streaming, Datenbank abfragen, downloads oder GPS Abfragen halt
 
B

Black Rider

Neues Mitglied
Hallo zusammen

Mit dem AlarmManager funktioniert es perfekt.

Eine Frage habe ich noch. Kann man von einer anderen Methode auf den sich wiederholdenen Alarm (alarmManager.setRepeating) zugreifen und den Intervall ändern?

Ich will standartmässig nur alle 5 oder sogar 10 Minuten die GPS Position abrufen. Wenn er aber merkt das ich in dieser Zeit 10KM zurckgelegt habe, soll er den Intervall verkleinern, damit die ganze Sache wieder präziser wird. Ebenso umgekehrt, soll der dann den Intervall wieder erhöhen wenn ich an der Stelle bleibe.

Gruss

Black Rider
 
Jaiel

Jaiel

Dauergast
Ich glaube so einen GPS listener artige Funktion gibt's nicht...Aber man kann ja die strecke auswerten wenn er sich mal die Daten holt

Hast du zum Beispiel alle 10 Minuten eingestellt und er sieht dass du nach 10 Minuten schon ein großes Stück zurück gelegt hast dann kannst du den Alarm ja neu stellen auf 5 Minuten oder so und das gleiche genau anders Rum

Aber leider wird das dann eben nur verzögert eintreten beim nächsten Intervall
 
D

deek

Stammgast
Ich würde es an deiner Stelle folgendermaßen machen:

- ein Service mit Notification (setForeground) damit er nicht so schnell gekillt wird.
- In diesem Service per Play Services Api auf location updates registrieren (Receiving Location Updates | Android Developers)
- Bei Bedarf bei großer Änderung der Entfernung kannst du FINE_LOCATION anfragen um GPS Genauigkeit zu bekommen. Bei längerem Stillstand wieder abschalten.
- Im LocationCallback dann an deine DB schicken.

Damit brauchst du keinen AlarmManager der dich alle paar Minuten/Sekunden weckt, sondern bist komplett an die Location gebunden. Damit machst du auch kein Update wenn keins benötigt wird.
In der LocationAPI kannst du min. Intervall, max. Intervall etc. alles festlegen.
 
B

Black Rider

Neues Mitglied
Guten Morgen

Vielen Dank für die Tipps. Auch wenn die Weise mit den LocationUpdates von deek sicherlich die sauberere Lösung wäre, bleibe ich vorerst mal beim Alarmmanager.


Nur weiss ich gerade nicht, wie ich aus dem onReceive Event den Alarm neu setzen kann, aber mal weiter googeln :)

Gruss

Black Rider
 
Jaiel

Jaiel

Dauergast
ähm ich glaub das geht ganz einfach indem du in:

PHP:
public void setAlarmForNotification(int seconds) 
    { 
        long alarmTime=System.currentTimeMillis()+seconds*1000; 
        Intent myBroadcastReceiverIntent=new Intent(this,MyBroadcastReceiver.class); 
        AlarmManager alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE); 
        alarmManager.set(AlarmManager.RTC, alarmTime,PendingIntent.getBroadcast(this, 
                     1,myBroadcastReceiverIntent,PendingIntent.FLAG_UPDATE_CURRENT)); 
    }
alles was "this" enthält mit dem context objekt austauschst , plus du musst die getSystemService() methode mit dem context object aufrufen:

PHP:
public void setAlarmForNotification(int seconds) 
    { 
        long alarmTime=System.currentTimeMillis()+seconds*1000; 
        Intent myBroadcastReceiverIntent=new Intent(context,MyBroadcastReceiver.class); 
        AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
        alarmManager.set(AlarmManager.RTC, alarmTime,PendingIntent.getBroadcast(context, 
                     1,myBroadcastReceiverIntent,PendingIntent.FLAG_UPDATE_CURRENT)); 
    }
Ich hab es grad getestet und mein Handy zum Absturz gebracht indem ich immer wieder den Alarmmanager gesetzt habe. Scheint also ohne Probleme zu klappen.


lg
 
B

Black Rider

Neues Mitglied
Ahh, ist ja ganz einfach. Ok, das ist es immer wenn man weiss wie :) Vielen Dank :)

Gruss

Black Rider

Edit:

So, habe jetzt ein Intervall von max. 300 Sekunden. Sobald er zwei GPS Locations hat (Genauigkeit < 100) rechnet er die Meter pro Sekunde aus. Ich strebe eine Genauigkeit von 500 Meter Distanz zwischen den GPS Punkten an. Somit ergibt (500 / MeterproSekunde) den neuen Intervall für den Alarmtimer.

Wenn der Intervall durch die Berechnung schlagartig kleiner wird (Stillstand --> Bewegung), springt er sofort auf den kleinen Intervall.
Wenn der Intervall durch die BRechnung schlagartig grösser wird (Bewegung --> Stillstand), wird der Intervall nur um einen viertel der differenz zwischen des neuen und des alten Intervalls grösser.

Somit verhindere ich, das bei einer kurzen Pause sofort der Intervall wieder hoch schiesst.

Lass es jetzt mal so laufen. Fahre ja jeden Tag. Als nächstes kommt die Auswertung mittels C# Programm am PC. (Rechenleistung und mein Zuhause ;D). Kann dann ja dann mal die Ergebnisse zu diesem Vorgehen posten.
 
Zuletzt bearbeitet:
Jaiel

Jaiel

Dauergast
offtopic ... sorry hat mcih etwas gejuckt :"das Intervall":tongue:

Hört sich gut an viel Erfolg damit