Android: comment utiliser AlarmManager

89

J'ai besoin de déclencher un bloc de code après 20 minutes après le AlarmManagerréglage.

Quelqu'un peut-il me montrer un exemple de code sur la façon d'utiliser un AlarmManagerdans ِ Android?

Je joue avec du code depuis quelques jours et cela ne fonctionnera tout simplement pas.

À M
la source

Réponses:

109

"Quelques exemples de code" n'est pas si simple AlarmManager.

Voici un extrait montrant la configuration de AlarmManager:

AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);

mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);

Dans cet exemple, j'utilise setRepeating(). Si vous voulez une alarme à un coup, utilisez simplement set(). Assurez-vous de donner l'heure de début de l'alarme dans la même base de temps que celle utilisée dans le paramètre initial à set(). Dans mon exemple ci-dessus, j'utilise AlarmManager.ELAPSED_REALTIME_WAKEUP, donc ma base de temps est SystemClock.elapsedRealtime().

Voici un exemple de projet plus large montrant cette technique.

CommonsWare
la source
2
Rebonjour. Merci pour la réponse. Si j'achète votre livre, explique-t-il comment mettre en place un gestionnaire d'alarme en détail?
Tom le
7
Le livre Advanced Android (version 0.9) contient environ 9 pages couvrant AlarmManager, WakeLocks et le reste de cet exemple. Cela augmentera probablement légèrement dans la version 1.0 au fur et à mesure que je fais le correctif que j'ai mentionné dans ma réponse ci-dessus. Et si vous avez des questions concernant le livre ou son exemple de code, rendez -vous sur groups.google.com/group/cw-android et je serai ravi d'y répondre.
CommonsWare
17
Tout développeur Android devrait avoir un abonnement aux livres de Mark :) Au moins une fois
Bostone
1
@ MarioGalván: Vous devez le définir lorsque votre application est exécutée pour la première fois et lors d'un redémarrage.
CommonsWare
Je pense que vous devriez utiliser AlarmManager.RTC_WAKEUP si vous voulez qu'il se déclenche tout de suite, puis à chaque PERIOD. Dans votre code, il se déclenchera après SystemClock.elapsedRealtime () et ensuite chaque PERIOD.
Damon Yuan
66

Il y a quelques bons exemples dans l'exemple de code Android

. \ android-sdk \ samples \ android-10 \ ApiDemos \ src \ com \ example \ android \ apis \ app

Ceux à vérifier sont:

  • AlarmController.java
  • OneShotAlarm.java

Tout d'abord, vous avez besoin d'un récepteur, quelque chose qui peut écouter votre alarme lorsqu'elle est déclenchée. Ajoutez ce qui suit à votre fichier AndroidManifest.xml

<receiver android:name=".MyAlarmReceiver" />

Ensuite, créez la classe suivante

public class MyAlarmReceiver extends BroadcastReceiver { 
     @Override
     public void onReceive(Context context, Intent intent) {
         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

Ensuite, pour déclencher une alarme, utilisez ce qui suit (par exemple dans votre activité principale):

AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 30);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);

.


Ou, mieux encore, créez une classe qui gère tout et utilisez-la comme ça

Bundle bundle = new Bundle();
// add extras here..
MyAlarm alarm = new MyAlarm(this, bundle, 30);

de cette façon, vous avez tout en un seul endroit (n'oubliez pas de modifier le AndroidManifest.xml)

public class MyAlarm extends BroadcastReceiver {
    private final String REMINDER_BUNDLE = "MyReminderBundle"; 

    // this constructor is called by the alarm manager.
    public MyAlarm(){ }

    // you can use this constructor to create the alarm. 
    //  Just pass in the main activity as the context, 
    //  any extras you'd like to get later when triggered 
    //  and the timeout
     public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
         AlarmManager alarmMgr = 
             (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent intent = new Intent(context, MyAlarm.class);
         intent.putExtra(REMINDER_BUNDLE, extras);
         PendingIntent pendingIntent =
             PendingIntent.getBroadcast(context, 0, intent, 
             PendingIntent.FLAG_UPDATE_CURRENT);
         Calendar time = Calendar.getInstance();
         time.setTimeInMillis(System.currentTimeMillis());
         time.add(Calendar.SECOND, timeoutInSeconds);
         alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                      pendingIntent);
     }

      @Override
     public void onReceive(Context context, Intent intent) {
         // here you can get the extras you passed in when creating the alarm
         //intent.getBundleExtra(REMINDER_BUNDLE));

         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}
Défaut
la source
2
Salut! J'ai testé ce code et ça marche bien (+1). mais j'ai essayé cela pour plusieurs alarmes (comme une pendant 10 secondes, et une autre pendant 15, et seule la seconde est déclenchée. Est-ce que je fais quelque chose de mal, ou est-ce un problème majeur? EDIT: Ok, j'ai trouvé le problème ici : stackoverflow.com/questions/2844274/…
Nuno Gonçalves
FWIW, j'utiliserais une méthode statique plutôt qu'un constructeur pour cela.
Edward Falk
9

Ce que vous devez faire, c'est d'abord créer l'intention que vous devez planifier. Ensuite, obtenez le pendingIntent de cette intention. Vous pouvez programmer des activités, des services et des émissions. Pour planifier une activité, par exemple MyActivity:

  Intent i = new Intent(getApplicationContext(), MyActivity.class);
  PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
  PendingIntent.FLAG_CANCEL_CURRENT);

Donnez cet pendingIntent à alarmManager:

  //getting current time and add 5 seconds in it
  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.SECOND, 5);
  //registering our pending intent with alarmmanager
  AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
  am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);

Maintenant MyActivity sera lancé après 5 secondes du lancement de l'application, peu importe que vous arrêtiez votre application ou que votre appareil soit passé en état de veille (en raison de l'option RTC_WAKEUP). Vous pouvez lire un exemple de code complet Planification d'activités, de services et de diffusions #Android

SohailAziz
la source
+1 excellente réponse, exactement ce dont j'avais besoin, un exemple de travail.
A.Alqadomi
4

Je voulais faire un commentaire mais <50 rep, alors voilà. Rappel amical que si vous utilisez la version 5.1 ou supérieure et que vous utilisez un intervalle de moins d'une minute, cela se produit:

Suspiciously short interval 5000 millis; expanding to 60 seconds

Regardez ici .

kurt
la source
3

Quelques exemples de code lorsque vous souhaitez appeler un service à partir de Alarmmanager:

PendingIntent pi;
AlarmManager mgr;
mgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(DataCollectionActivity.this, HUJIDataCollectionService.class);    
pi = PendingIntent.getService(DataCollectionActivity.this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , 1000, pi);

Vous n'avez pas à demander les autorisations des utilisateurs.

L'aventure de la publicité numérique
la source
Une abréviation très courante.
Phantômaxx
0

Un AlarmManager est utilisé pour déclencher du code à un moment précis.

Pour démarrer un gestionnaire d'alarmes, vous devez d'abord obtenir l'instance du système. Puis passez le PendingIntent qui serait exécuté à un moment futur que vous spécifiez

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent alarmIntent = new Intent(context, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
int interval = 8000; //repeat interval
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);

Vous devez être prudent lorsque vous utilisez le gestionnaire d'alarme. Normalement, un gestionnaire d'alarmes ne peut pas répéter avant une minute. En mode basse consommation également, la durée peut augmenter jusqu'à 15 minutes.

Faxriddin Abdullayev
la source