Comment vérifier si AlarmManager possède déjà un jeu d’alarmes?

Lorsque mon application démarre, je souhaite qu’elle vérifie si une alarme particulière (enregistrée via AlarmManager) est déjà définie 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 correct? Je dois faire cette vérification afin d’informer l’utilisateur avant toute action pour créer une nouvelle alarme.

    Suite au commentaire posté, 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 si elle est active consiste à:

     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, comme décrit dans le javadoc: if the described PendingIntent **does not** already exists, then simply return null (au lieu d’en créer un nouveau)

    Pour ceux qui en ont besoin, voici une réponse.

    Utilisez l’ adb shell dumpsys alarm

    Vous pouvez savoir que l’alarme a été réglée et quand ils sont en alarme et en intervalle. Combien de fois cette alarme a-t-elle été invoquée?

    Exemple de travail avec récepteur (la première réponse était juste avec action).

     //starting AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(getActivity(), MyReceiver.class); intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//my custom ssortingng action name PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap //and stopping Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up alarmManager.cancel(pendingIntent);//important pendingIntent.cancel();//important //checking if alarm is working with pendingIntent Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up boolean isWorking = (PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag Log.d(TAG, "alarm is " + (isWorking ? "" : "not") + " working..."); 

    Il convient de mentionner:

    Si l’application de création plus tard (process) récupère le même type de PendingIntent (même opération , même intention – action, données, catégories, composants, indicateurs ), elle recevra un PendingIntent représentant le même jeton si cela est toujours valide, et peut donc appeler cancel () pour le supprimer.

    En bref, votre PendingIntent doit avoir les mêmes fonctionnalités (structure d’opération et d’intention) pour en prendre le contrôle.

    Notez cette citation de la documentation pour le gestionnaire d’alarmes:

    S’il existe déjà une alarme pour cette intention planifiée (avec l’égalité des deux intentions étant définie par Intent.filterEquals), elle sera alors supprimée et remplacée par celle-ci.

    Ne vous préoccupez pas de savoir si l’alarme existe si vous essayez de décider de créer une alarme ou non. Il suffit de le créer à chaque démarrage de votre application. Vous allez remplacer les alarmes passées que vous avez configurées.

    Vous avez besoin d’une approche différente si vous essayez de calculer le temps qu’il rest sur une alarme créée précédemment ou si vous avez vraiment besoin de savoir si une telle alarme existe. Pour répondre à ces questions, envisagez d’enregistrer les données de préférences partagées au moment de la création de l’alarme. Vous pouvez enregistrer l’horodatage de l’horloge au moment où l’alarme a été définie, l’heure à laquelle l’alarme doit se déclencher et la période de répétition (si vous avez configuré une alarme répétitive).

    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"); 

    la chose est qu’avec diff extras l’intention (et l’alarme) ne sera pas unique. Afin de pouvoir identifier quelle alarme est active ou non, j’ai dû définir diff- 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); 

    Je viens de trouver une autre solution, cela semble fonctionner pour moi

     Intent myIntent = new Intent(MainActivity.this, MyReceiver.class); boolean isWorking = (PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_NO_CREATE) != null); if (isWorking) {Log.d("alarm", "is working");} else {Log.d("alarm", "is not working");} if(!isWorking) { pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); int timeNotif = 5 * 60 * 1000;//time in ms, 7*24*60*60*1000 for 1 week Log.d("Notif", "Notification every (ms): " + timeNotif); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), timeNotif, pendingIntent); } 

    J’ai fait un simple script bash (stupide ou pas), qui extrait les longs du shell adb, les convertit en timestamps et les affiche en rouge.

     echo "Please set a search filter" read search adb shell dumpsys alarm | grep $search | (while read i; do echo $i; _DT=$(echo $i | grep -Eo 'when\s+([0-9]{10})' | tr -d '[[:alpha:][:space:]]'); if [ $_DT ]; then echo -e "\e[31m$(date -d @$_DT)\e[0m"; fi; done;) 

    essayez-le;)

    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 un Alarm_last_set_time enregistré quelque part, et avoir un object On_boot_starter BroadcastReciever: BOOT_COMPLETED quelque chose.

      Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION"); PendingIntent pendingIntent = PendingIntent.getBroadcast( sqlitewraper.context, 0, intent, PendingIntent.FLAG_NO_CREATE); 

    FLAG_NO_CREATE n’est pas créé en attente de manière à donner une valeur booléenne fausse.

      boolean alarmUp = (PendingIntent.getBroadcast(sqlitewraper.context, 0, new Intent("com.my.package.MY_UNIQUE_ACTION"), PendingIntent.FLAG_NO_CREATE) != null); if (alarmUp) { System.out.print("k"); } AlarmManager alarmManager = (AlarmManager) sqlitewraper.context .getSystemService(Context.ALARM_SERVICE); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pendingIntent); 

    Une fois que AlarmManager a vérifié la valeur de l’intention en attente, il donne la valeur true car AlarmManager met à jour l’indicateur de l’intention en attente.

      boolean alarmUp1 = (PendingIntent.getBroadcast(sqlitewraper.context, 0, new Intent("com.my.package.MY_UNIQUE_ACTION"), PendingIntent.FLAG_UPDATE_CURRENT) != null); if (alarmUp1) { System.out.print("k"); } 

    Alors que presque tout le monde ici a donné la bonne réponse, aucun organisme n’a expliqué sur quelle base les alarmes fonctionnent

    Vous pouvez en apprendre davantage sur AlarmManager et son fonctionnement ici . Mais voici la réponse rapide

    Vous voyez que AlarmManager planifie essentiellement un PendingIntent à un moment donné. Donc, pour annuler l’alarme programmée, vous devez annuler l’ PendingIntent .

    Notez toujours deux choses lors de la création du PendingIntent

     PendingIntent.getBroadcast(context,REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    • Demande de code – Agit comme identifiant unique
    • Flag – Définit le comportement de PendingIntent

    Maintenant, pour vérifier si l’alarme est déjà programmée ou pour annuler l’alarme, il vous suffit d’avoir access au même PendingIntent . Cela peut être fait si vous utilisez le même code de demande et utilisez FLAG_NO_CREATE comme indiqué ci-dessous

     PendingIntent pendingIntent=PendingIntent.getBroadcast(this,REQUEST_CODE,intent,PendingIntent.FLAG_NO_CREATE); if (pendingIntent!=null) alarmManager.cancel(pendingIntent); 

    Avec FLAG_NO_CREATE il retournera null si le PendingIntent n’existe pas déjà. S’il existe déjà, il renvoie une référence au PendingIntent existant