256 votes

Comment vérifier si une alarme est déjà définie dans le AlarmManager ?

Lorsque mon application démarre, je veux qu'elle vérifie si une alarme particulière (enregistrée via AlarmManager) est déjà réglée et en cours d'exécution. Les résultats de Google semblent indiquer qu'il n'y a aucun moyen de le faire. Est-ce toujours le cas ? J'ai besoin d'effectuer cette vérification afin d'informer l'utilisateur avant toute action visant à créer une nouvelle alarme.

8 votes

Veuillez valider la réponse qui a résolu votre problème ou publier votre propre solution.

334voto

Chris Knight Points 7946

Pour faire suite au commentaire de Ron, voici la solution détaillée. Disons que vous avez enregistré une alarme répétitive avec une intention en attente comme ceci :

Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, 
                                      intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 1);

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, pendingIntent);

La façon de vérifier s'il est actif est la suivante :

boolean alarmUp = (PendingIntent.getBroadcast(context, 0, 
        new Intent("com.my.package.MY_UNIQUE_ACTION"), 
        PendingIntent.FLAG_NO_CREATE) != null);

if (alarmUp)
{
    Log.d("myTag", "Alarm is already active");
}

La clé ici est le FLAG_NO_CREATE qui est décrit dans la javadoc : if the described PendingIntent **does not** already exists, then simply return null (au lieu d'en créer un nouveau)

9 votes

Doit-il utiliser l'intention avec seulement une chaîne d'action ? J'ai essayé de spécifier une classe, new Intent(context, MyClass.class) mais cela ne semble pas fonctionner. Il renvoie toujours un résultat nul, même lorsque l'alarme est en cours d'exécution.

5 votes

Toc777, non, il doit s'agir d'une chaîne qui correspond à une action déclarée dans votre filtre d'intention dans votre manifest.xml.

4 votes

Chris, c'est une autre question qui a causé mon problème. L'intention que j'ai mentionnée ci-dessus fonctionne effectivement :)

126voto

Jack Feng Points 41

Pour les autres qui en auraient besoin, voici une réponse.

Utilisez adb shell dumpsys alarm

Vous pouvez savoir que l'alarme a été réglée et à quel moment elle va être déclenchée et à quel intervalle. Vous pouvez également savoir combien de fois cette alarme a été déclenchée.

41 votes

Pas vraiment une réponse programmatique à l'OP, mais une astuce sympa. Très bon à savoir.

2 votes

Ajouter un grep pour filtrer la liste habituellement longue des alarmes : adb shell dumpsys alarm | grep <e.g. package name of your app> Fonctionne également sur les nouveaux systèmes Windows (j'utilise Win10)

4 votes

Grep est exécuté sur l'appareil mobile, pas sur votre PC. Donc, si grep fonctionne, cela dépend du système d'exploitation Android. Les téléphones plus anciens ne disposent pas de grep.

11voto

HiB Points 1069

J'ai 2 alarmes. J'utilise l'intention avec des extras au lieu de l'action pour identifier les événements :

Intent i = new Intent(context, AppReciever.class);
i.putExtra("timer", "timer1");

Le problème est qu'avec différents extras, l'intention (et l'alarme) ne sera pas unique. Donc, pour pouvoir identifier quelle alarme est active ou non, j'ai dû définir différents types d'alarme. requestCode -s :

boolean alarmUp = (PendingIntent.getBroadcast(context, MyApp.TIMER_1, i, 
                    PendingIntent.FLAG_NO_CREATE) != null);

et voici comment l'alarme a été créée :

public static final int TIMER_1 = 1;
public static final int TIMER_2 = 2;

PendingIntent pending = PendingIntent.getBroadcast(context, TIMER_1, i,
            PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
            cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);
pending = PendingIntent.getBroadcast(context, TIMER_2, i,
            PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
            cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);

0 votes

En utilisant les suppléments d'intention et cette solution a fonctionné pour moi. Le seul changement est que j'utilise le service et que je l'ai changé en PendingIntent.getService

0voto

Stephen Points 26

J'ai l'impression qu'il n'y a aucun moyen de le faire, mais ce serait bien.

Vous pouvez obtenir un résultat similaire en ayant une Alarme_dernière_heure enregistrée quelque part, et en ayant un On_boot_starter BroadcastReciever:BOOT_COMPLETED genre de chose.

0voto

fiction Points 4261

Parlez-vous du réveil - dont la source peut être téléchargée à partir d'ici - ? http://Android.git.kernel.org/?p=platform/packages/apps/AlarmClock.git;a=tree;hb=HEAD

Ou bien vous parlez de fixer le moment où une tâche donnée doit être exécutée - http://developer.Android.com/reference/Android/app/AlarmManager.html

EDIT : Il semble que la source de AlarmClock soit supprimée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X