AlarmManager, BroadcastReceiver et le service ne fonctionnent pas
Je suis refactoring du code, de sorte que mon application va extraire des données à partir d'un site web une fois par jour à un moment donné. D'après mes recherches, il semble que AlarmManager
est l'approche la plus appropriée.
Le tutoriel que j'ai suivi est: http://mobile.tutsplus.com/tutorials/android/android-fundamentals-downloading-data-with-services/
Jusqu'à présent, AlarmManager
et la BroadcastReceiver
semblent être au travail, cependant la Service
semble ne jamais démarrer (ie. onStartCommand
ne semble pas être appelé)
Voici les bouts de code que j'ai pour l'instant:
MyActivity.java
private void setRecurringAlarm(Context context) {
Calendar updateTime = Calendar.getInstance();
updateTime.setTimeZone(TimeZone.getDefault());
updateTime.set(Calendar.HOUR_OF_DAY, 20);
updateTime.set(Calendar.MINUTE, 30);
Intent downloader = new Intent(context, AlarmReceiver.class);
downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//should be AlarmManager.INTERVAL_DAY (but changed to 15min for testing)
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);
Log.d("MyActivity", "Set alarmManager.setRepeating to: " + updateTime.getTime().toLocaleString());
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent dailyUpdater = new Intent(context, MyService.class);
context.startService(dailyUpdater);
Log.d("AlarmReceiver", "Called context.startService from AlarmReceiver.onReceive");
}
}
MyService.java
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "About to execute MyTask");
new MyTask().execute();
return Service.START_FLAG_REDELIVERY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private class MyTask extends AsyncTask<String, Void, boolean> {
@Override
protected boolean doInBackground(String... strings) {
Log.d("MyService - MyTask", "Calling doInBackground within MyTask");
return false;
}
}
}
AndroidManifest.xml
<application ...>
...
<service android:name="MyService"></service>
<receiver android:name="AlarmReceiver"></receiver>
</application>
Quand je déclencher la setRecurringAlarm
dans MyActivity
le journal s'imprime comme prévu, de même, toutes les 15min, le journal de AlarmReceiver
s'affiche. Cependant, je n'ai jamais voir le journal de MyService
🙁
Exemple de ce que je vois dans les logs:
DEBUG/MyActivity(688): Set alarmManager.setRepeating to: Jan 29, 2012 8:30:06 PM
DEBUG/AlarmReceiver(688): Called context.startService from AlarmReceiver.onReceive
DEBUG/AlarmReceiver(688): Called context.startService from AlarmReceiver.onReceive
N'arrive pas à comprendre ce que j'ai fait de mal, ma compréhension de la Android Dev Docs est que dans AlarmReceiver
quand je l'appelle context.startService(dailyUpdater)
qui devrait à son tour appel onStartCommand
dans MyService
mais cela ne semble pas être le cas!
Ce que je fais mal qui est à l'origine MyService
de ne pas commencer du tout?
source d'informationauteur pyko | 2012-01-29
Vous devez vous connecter pour publier un commentaire.
Compris!
MyService doit être l'extension de IntentService au lieu de Service!
Avec ce changement, cela signifie également que, au lieu de l'annulation de la
onStartCommand
doit être majeuronHandleIntent
à la place (voir docs sur IntentService)Donc MyService ressemble maintenant à ceci:
Note: à Partir de la documentation, le défaut de mise en œuvre de
onBind
retournenull
donc pas besoin de le remplacer.Plus d'informations sur l'extension de
IntentService
: http://developer.android.com/guide/topics/fundamentals/services.html#ExtendingIntentServiceVous pourriez obtenir AlarmManager pour exécuter le Service tout de suite plutôt que de passer par un BroadcastReceiver, si vous changez d'intention comme ceci:
Cela peut résoudre votre problème!
Au lieu d'utiliser
Intent dailyUpdater = new Intent(context, MyService.class);
utilisation
Intent dailyUpdater = new Intent(this, MyService.class);
Autre suggestion est de commencer directement à partir de l'alarme, plutôt que d'envoyer de diffusion et de commencer le service de récepteur de radiodiffusion.