Android selben Service mehrmals Aufrufen

droidStep

Mitglied
Hallo leute :meld:
ich programmiere schon etwas länger android apps, allerdings brauche ich jetzt zum ersten mal die service klasse. Ich möchte eine app programmieren bei der man ereignisse erstellen kann zu welcher uhrzeit was geschehen soll. dazu brauche ich eine activity in der man neue ereignisse hinzufügen kann und einen service der dies dann zur gegebenen uhrzeit ausführt. Das klappt schon ganz gut bis auf dass wenn ich zb einen service für 16:30 festgelegt habe und anschließend einen zweiten um 17:00 dann wird der erste einfach "überschrieben" und nur der zweite wird ausgeführt. Beide werden von derselben service klasse ausgeführt. Liegt vielleicht hierbei das problem?

die Methode die den Service erstellt:
Java:
private void createService(int function, int hour, int minute, int on_or_off){
    	int extra = function*2+on_or_off;
    	
    	Intent intent = new Intent(AddEreignisActivity.this, EasyManagerService.class);
    	intent.putExtra("function", extra);
    	PendingIntent pendingIntent = PendingIntent.getService(AddEreignisActivity.this, 0, intent, 0);
    	
    		
    	AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
  	           
    	Calendar calendar = Calendar.getInstance();
    	int hour_dif = hour-calendar.get(Calendar.HOUR_OF_DAY);
    	int minute_dif = minute-calendar.get(Calendar.MINUTE);
    	int second_dif = -calendar.get(Calendar.SECOND);
    	calendar.add(Calendar.HOUR_OF_DAY, hour_dif);
    	calendar.add(Calendar.MINUTE, minute_dif);
    	calendar.add(Calendar.SECOND, second_dif);
    	
    	alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    }

wenn ich nun diese methode 2 mal mit zb anderen zeitwerten aufrufe wird nur der zuletzt erstellte service ausgeführt.

Und ich hätte nocheine frage: geht es dass ich einen service erstelle der regelmäßig (also zb jeden montag um 17:00) ausgeführt wird?

danke schonmal für eure antworten :)
 

mjdv

Bekanntes Mitglied
Hallo,

also das mit dem AlarmManager sieht erstmal gut aus. Allerdings beim PedingIntent.getService, gibst du als Flags 0 an, keine Ahnung was für Auswirkungen das hat.

Schau mal hier nach den Flags: PendingIntent | Android Developers

Spontan würde das Flag Update current am besten passen. Dann läuft dein Service zwar auch nur einmal, aber wenn er schon läuft wird einfach die onStart Methode dann aufgerufen ohne ihn nochmal zu kreieren.

EDIT: Ne warte mal, genau das ist das Problem was du ja hast, das der alte einfach überschrieben wird.

Vielleicht doch FLAG_ONE_SHOT? Obwohl ich nciht so ganz verstehe was das jetzt macht.
 
Zuletzt bearbeitet:

schlingel

Gesperrter Benutzer
Was genau hast du vor? Warum willst du einem Service in zeitlichen Abständen Intents senden?

So ganz sinnvoll erscheint mir das im Moment nämlich nicht.

Und wie genau läuft der Service? Es gibt nämlich immer nur einen und dieser eine Service muss in onStartCommand auf eintrudelnden Intents reagieren. (oder du verwendest einen Binding, aber das ist noch ungeeigneter)
 
Zuletzt bearbeitet:

droidStep

Mitglied
Vielleicht doch FLAG_ONE_SHOT? Obwohl ich nciht so ganz verstehe was das jetzt macht.

jetzt startet auch nur der 2. service allerdings wird das extra vom 1. service übergeben ???:L


Was genau hast du vor? Warum willst du einem Service in zeitlichen Abständen Intents senden?

So ganz sinnvoll erscheint mir das im Moment nämlich nicht.

Und wie genau läuft der Service? Es gibt nämlich immer nur einen und dieser eine Service muss in onStartCommand auf eintrudelnden Intents reagieren. (oder du verwendest einen Binding, aber das ist noch ungeeigneter)

der service soll zb um 15:00 wlan einschalten (was im extra "function" gespeicher ist) und um zb 17:00 wlan wieder ausschalten.
was ist ein binding genau bin mit google schon drauf gestoßen weiss aber nich genau was das ist. hat was mit der onBind() methode zu tun oder?
 

schlingel

Gesperrter Benutzer
OK, dann solltest du das vielleicht als IntentService und nicht als Service abbilden. Der Unterschied zwischen IntentService und Service ist der, dass der IntentService sich vollkommen autark um den eigenen Lifecycle kümmert und sich eine Job-Queue aufbaut falls mehrere Intents auf einmal reintrudeln. Die werden dann seriell hintereinander in einem eigenen Thread ausgeführt.

Warum ist das gut? In deiner Service-Implementierung ist der Hund drin. Du willst ja nicht jedes Mal einen neuen Service öffnen, was ja so gar nicht funktioniert, du brauchst einen einzigen Service der zu bestimmten Zeitpunkten Aktionen durchführt. Wie diese Aktionen aussehen definierst du am besten anhand des Intents. Da steht dann z.B. der Name der Klasse drinnen die instanziert werden soll oder einfach nur die Request-ID als Integer und der IntentService reagiert darauf.

Java:
public class MyIntentService extends IntentService {
  public static final String REQUEST_ID = "REQUEST_ID";

  // [...] default methoden die gebraucht werden. Weiß ich nicht auswendig

  // diese methode wird aufgerufen sobald der intent eintrudelt. 
  // Wann er eintrudelt regelst du mit dem Alarm-Manager
  // und den PendingIntents.
  public void onHandleIntent(Intent job) {
    int reqID = job.getExtras().getInt(REQUEST_ID);

    switch(reqID) {
      case 0: // [...] wlan aufdrehen
         break; 
      case 1: // [...] zeug runterladen
         break;
    }
  }
}
 

droidStep

Mitglied
logcat:
Code:
07-09 14:55:42.493: D/dalvikvm(20439): GC_CONCURRENT freed 108K, 2% free 9183K/9351K, paused 2ms+3ms
07-09 14:55:42.608: D/dalvikvm(20439): GC_CONCURRENT freed 255K, 4% free 9406K/9735K, paused 3ms+2ms
07-09 14:56:09.283: D/dalvikvm(20439): newInstance failed: no <init>()
07-09 14:56:09.288: D/AndroidRuntime(20439): Shutting down VM
07-09 14:56:09.288: W/dalvikvm(20439): threadid=1: thread exiting with uncaught exception (group=0x40c421f8)
07-09 14:56:09.298: E/AndroidRuntime(20439): FATAL EXCEPTION: main
07-09 14:56:09.298: E/AndroidRuntime(20439): java.lang.RuntimeException: Unable to instantiate service my.easy.manager.EasyManagerService: java.lang.InstantiationException: can't instantiate class my.easy.manager.EasyManagerService; no empty constructor
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at android.app.ActivityThread.handleCreateService(ActivityThread.java:2249)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at android.app.ActivityThread.access$1600(ActivityThread.java:127)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1213)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at android.os.Looper.loop(Looper.java:137)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at android.app.ActivityThread.main(ActivityThread.java:4507)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at java.lang.reflect.Method.invokeNative(Native Method)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at java.lang.reflect.Method.invoke(Method.java:511)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at dalvik.system.NativeStart.main(Native Method)
07-09 14:56:09.298: E/AndroidRuntime(20439): Caused by: java.lang.InstantiationException: can't instantiate class my.easy.manager.EasyManagerService; no empty constructor
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at java.lang.Class.newInstanceImpl(Native Method)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at java.lang.Class.newInstance(Class.java:1319)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	at android.app.ActivityThread.handleCreateService(ActivityThread.java:2246)
07-09 14:56:09.298: E/AndroidRuntime(20439): 	... 10 more
 

droidStep

Mitglied
als ich noch keinen Konstruktor hatte wurde ich dazu aufgefordert einen hinzuzufügen und als ich ihn automatisch hinzufügen lies erschien das hier:
Java:
public EasyManagerService(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

wenn ich den parameter entferne und statt super(name) super(null) schreibe gehts auch nicht und super() kann ich nicht weglassen
 

schlingel

Gesperrter Benutzer
Ich weiß, das ist ganz angenehm wenn einer so blöd ist und einem die Doku übersetzt, aber in Zukunft schau doch einfach nach wofür das gut ist.

Der Konstruktor mit einem String-Parameter ist dafür da, um einen Namen zu setzen. Also musst du in deinem Konstruktor ohne Parameter super aufrufen mit einem Namen. Denn kannst du dir aussuchen. Der qualifizierte Typname bietet sich an.

Java:
public EasyManagerService() {
  super(EasyManagerService.class.getName());
}
 

droidStep

Mitglied
ok danke
ich will ja nich auf die nerven gehn aber jetzt gehts immernoch nich:
logcat:
Code:
07-09 15:15:33.263: I/Process(21806): Sending signal. PID: 21806 SIG: 9
07-09 15:16:36.503: I/dalvikvm(22436): Turning on JNI app bug workarounds for target SDK version 10...
07-09 15:16:36.618: D/AndroidRuntime(22436): Shutting down VM
07-09 15:16:36.618: W/dalvikvm(22436): threadid=1: thread exiting with uncaught exception (group=0x40c421f8)
07-09 15:16:36.618: E/AndroidRuntime(22436): FATAL EXCEPTION: main
07-09 15:16:36.618: E/AndroidRuntime(22436): java.lang.RuntimeException: Unable to start service my.easy.manager.EasyManagerService@414e9608 with Intent { flg=0x4 cmp=my.easy.manager/.EasyManagerService (has extras) }: java.lang.NullPointerException
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2388)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.app.ActivityThread.access$1900(ActivityThread.java:127)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1222)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.os.Looper.loop(Looper.java:137)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.app.ActivityThread.main(ActivityThread.java:4507)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at java.lang.reflect.Method.invokeNative(Native Method)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at java.lang.reflect.Method.invoke(Method.java:511)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at dalvik.system.NativeStart.main(Native Method)
07-09 15:16:36.618: E/AndroidRuntime(22436): Caused by: java.lang.NullPointerException
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.app.IntentService.onStart(IntentService.java:116)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at my.easy.manager.EasyManagerService.onStart(EasyManagerService.java:47)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.app.IntentService.onStartCommand(IntentService.java:130)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2371)
07-09 15:16:36.618: E/AndroidRuntime(22436): 	... 10 more
 

schlingel

Gesperrter Benutzer
07-09 15:16:36.618: E/AndroidRuntime(22436): Caused by: java.lang.NullPointerException
07-09 15:16:36.618: E/AndroidRuntime(22436): at android.app.IntentService.onStart(IntentService.java:116)
07-09 15:16:36.618: E/AndroidRuntime(22436): at my.easy.manager.EasyManagerService.onStart(EasyManagerService.java:47)

Exceptions, wenn du Glück hast, sagen dir eh alles was du brauchst. Diese tut es. Da ist was null was nicht null sein soll in Zeile 47 von EasyManagerService.java.
 

droidStep

Mitglied
hab das problem gelöst indem ich bei

Java:
@Override
	public void onStart(Intent intent, int startId){
		super.onStart(intent, startId);
		
	}

des
Java:
super.onStart(intent, startId);

rausgenommen habe.
darf ich das?
naja jetzt funktionierts ohne absturz allerdings wird immernoch nur die 2. aufgabe ausgeführt

[EDIT]hab ne bessere lösung gefunden:
Java:
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {

		super.onStartCommand(intent, startId, startId);
		
     	return START_STICKY;
	}
[/EDIT]

ich versteh zwar nicht was das bedeutet aber ich hab nach langem googlen das hier gefunden und es funktioniert ^^
 
Zuletzt bearbeitet:

droidStep

Mitglied
ich weiss jetzt warum der service nicht 2 mal "aufgerufen" sondern nur "überschrieben" wird

Java:
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);

in der definition von alarmManager.set() steht "If there is already an alarm for this Intent scheduled (with the equality of two intents being defined by filterEquals(Intent)), then it will be removed and replaced by this one. "

bedeutet doch dass er den ersten intent einfach überschreibt wenn ich diese methode ein zweites mal aufzufe oder?

aber wie umgehe ich das jetzt am besten?
 

schlingel

Gesperrter Benutzer
bedeutet doch dass er den ersten intent einfach überschreibt wenn ich diese methode ein zweites mal aufzufe oder?
Ja, so sehe ich das auch. Ziemlich blöd wenn du mich fragst. Wie das zu überschreiben ist, ist eine gute Frage. Ich glaube du musst da einen Workaround bauen.

Also wenn du so einen Alarm setzen willst, musst du erst einmal den neuen Alarm speichern. Dann setzt du per AlarmManager den neuen Alarm wenn er vor dem frühesten der anderen Alarme sitzt.

Wenn dann ein Alarm feuert, setzt du im Service anhand deiner gespeicherten Liste den Intent neu und löscht den Eintrag aus deiner Datenbank/File/was auch immer.

Möglicherweise sind die Leute auf Stackoverflow gescheiter, frag dort auch mal anch.
 

droidStep

Mitglied
ok an sowas ähnliches hatte ich auch schon gedacht, hab aber gehofft es geht auch einfacher und sicherer. Dann werd ichs mal so machen.

Danke nochmal für die Hilfe ! :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Klasse im selben Package aufrufen Android & Cross-Platform Mobile Apps 18
G Randomgenerator liefert immer wieder die selben Zahlen Android & Cross-Platform Mobile Apps 16
W Wieso gehen Log nicht im Service? Android & Cross-Platform Mobile Apps 20
W Background Service Daten verarbeiten/Schleife ect. Android & Cross-Platform Mobile Apps 1
L Unzuverlässiger Service Android & Cross-Platform Mobile Apps 1
J Service starte nicht mehr Android & Cross-Platform Mobile Apps 13
J intend Service im Android Studio Android & Cross-Platform Mobile Apps 4
L Eingaben in der MainActivity einem Service übergeben Android & Cross-Platform Mobile Apps 0
L Prüfen ob Service läuft Android & Cross-Platform Mobile Apps 3
N Android Game Background Service Android & Cross-Platform Mobile Apps 11
Excess Android Service läuft nicht in Sandby weiter Android & Cross-Platform Mobile Apps 2
G GPS in einem Service abfragen Android & Cross-Platform Mobile Apps 2
D Java ME Bild vom Web-Service aus zurück geben Android & Cross-Platform Mobile Apps 8
T Android Datenbankverbindung in Service für Push Notification Android & Cross-Platform Mobile Apps 0
G Thread in einer Service erstellen Android & Cross-Platform Mobile Apps 0
S Android In Service überprüfen ob eine Activity gebunden ist? Android & Cross-Platform Mobile Apps 6
S Android Kommunikation zwischen UI -> Service -> Thread Android & Cross-Platform Mobile Apps 4
C Android Kommunikation zwischen Service und Activity Android & Cross-Platform Mobile Apps 8
L Android Zugriff aus unbound Service auf Preferences Android & Cross-Platform Mobile Apps 2
Noahscript Android Socket.connect() wiederholt sich mehrmals? Android & Cross-Platform Mobile Apps 4

Ähnliche Java Themen

Neue Themen


Oben