I'm coding a 'simple' notificator which consists on calling to a website, checking the response and notifying if there's something new.
I'm using a Service to do the http operations and I'd like AlarmManager to repeat the call to the Service with a given frequency. I've been checking tutorials like this and other examples and, since I want the service to be scheduled either whenever the user leaves the settings screen (the only Activity it has so far) and after BOOT is completed, so I created a class to wrap the scheduling code.
public class Scheduler {
public static boolean cancelScheduledService(Context ctx, Intent serviceIntent) {
boolean success = true;
Log.v("novUmbria", "Scheduler.cancelScheduledService");
try {
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
am.cancel(
PendingIntent.getBroadcast(
ctx, 0,
new Intent(ctx, NotificadorService.class),
// si ya existe, no genera un 2º
PendingIntent.FLAG_CANCEL_CURRENT
)
);
Log.v("novUmbria", "Scheduler.cancelScheduledService Servicio cancelado");
} catch (Exception e) {
Log.e("novUmbria", "Scheduler.cancelScheduledService Excepción: " + e.getMessage());
success = false;
}
return success;
}
public static boolean scheduleService(Context ctx, Intent serviceIntent, long interval) {
boolean success = true;
Log.v("novUmbria", "Scheduler.scheduleService Servicio ");
try {
Calendar cal = Calendar.getInstance();
SimpleDateFormat timeformat = new SimpleDateFormat("HH:mm");
// timeformat.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(
// am.setInexactRepeating(
// AlarmManager.ELAPSED_REALTIME_WAKEUP,
AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(),
interval,
PendingIntent.getBroadcast(
ctx, 0,
new Intent(ctx, NotificadorService.class),
// si ya existe, no genera un 2º
PendingIntent.FLAG_CANCEL_CURRENT
)
);
Log.v("novUmbria", "Scheduler.scheduleService Servicio programado a las "
+ timeformat.format(cal.getTime())
+ " cada " + (interval / 60000) + " minutos"
);
startService(ctx, serviceIntent);
Log.v("novUmbria", "Scheduler.scheduleService Servicio iniciado"
);
} catch (Exception e) {
Log.e("novUmbria", "Scheduler.scheduleService Excepción: " + e.getMessage());
success = false;
}
return success;
}
public static boolean startService(Context ctx, Intent serviceIntent) {
boolean success = true;
Log.v("novUmbria", "Scheduler.startService");
try {
ctx.startService(serviceIntent);
Log.v("novUmbria", "Scheduler.startService Servicio iniciado");
} catch (Exception e) {
Log.e("novUmbria", "Scheduler.startService Excepción: " + e.getMessage());
success = false;
}
return success;
}
}
Here's the call to the scheduler from the settings Activity
//Settings Activity
@Override
protected void onStop() {
Log.v("novUmbria", "SettingsActivity.onStop");
Intent serviceIntent = new Intent(getApplicationContext(), NotificadorService.class);
Scheduler.cancelScheduledService(getApplicationContext(), serviceIntent);
long frequency = 1000 * 60 / 2;
Scheduler.scheduleService(getApplicationContext(),
serviceIntent,
frequency
);
Log.v("novUmbria", "SettingsActivity.onStop scheduleService");
super.onStop();
}
Thing is: logcat tells me the service gets scheduled (or, better said, that it doesn't raise an Exception) and it gets executed for the first time. But, after that, no matter how long or short the interval is, it never repeats. I've tried several flags RTC, RTC_WAKEUP, ELAPSED_REALTIME etc, but I got nothing.
My testing device is a Nexus 4 fully updated. I've even rebooted it, so I checked the BOOT_COMPLETE receiver worked ok, but it never repeats the service calls.
Any ideas on where's the problem?
Thanks in advance.
I've found the answer here.
Apparently, when you want to schedule a SERVICE, you don't use
PendingIntent.getBroadcast
butPendingIntent.getService
.Just that little change and it's repeating as it should.
Hope this helps someone else :)