Recherche…


Exécuter une intention ultérieurement

  1. Créez un récepteur. Cette classe recevra l'intention et la traitera comme vous le souhaitez.
public class AlarmReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Handle intent
        int reqCode = intent.getExtras().getInt("requestCode");
        ...
    }
}
  1. Donnez une intention à AlarmManager. Cet exemple déclenchera l'intention d'être envoyé à AlarmReceiver après 1 minute.
final int requestCode = 1337;
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 60000 , pendingIntent );

Comment annuler une alarme

Si vous souhaitez annuler une alarme et que vous n'avez pas de référence au PendingIntent d'origine utilisé pour définir l'alarme, vous devez recréer un PendingIntent exactement comme lors de sa création initiale.

Un Intent est considéré comme égal par le AlarmManager :

si leur action, données, type, classe et catégories sont les mêmes. Cela ne compare aucune donnée supplémentaire incluse dans les intentions.

Le code de demande de chaque alarme est généralement défini comme une constante:

public static final int requestCode = 9999;

Donc, pour une simple alarme configurée comme ceci:

Intent intent  = new Intent(this, AlarmReceiver.class);
intent.setAction("SomeAction");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, targetTimeInMillis, pendingIntent);

Voici comment créer une nouvelle référence PendingIntent que vous pouvez utiliser pour annuler l’alarme avec une nouvelle référence AlarmManager:

Intent intent  = new Intent(this, AlarmReceiver.class);
intent.setAction("SomeAction");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_NO_CREATE);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
if(pendingIntent != null) {
    alarmManager.cancel(pendingIntent);
}

Création d'alarmes exactes sur toutes les versions Android

Avec de plus en plus d'optimisations de la batterie dans le système Android au fil du temps, les méthodes du AlarmManager ont également considérablement changé (pour permettre une synchronisation plus souple). Cependant, pour certaines applications, il doit toujours être aussi précis que possible sur toutes les versions Android. L'assistant suivant utilise la méthode la plus précise disponible sur toutes les plates-formes pour planifier un PendingIntent :

public static void setExactAndAllowWhileIdle(AlarmManager alarmManager, int type, long triggerAtMillis, PendingIntent operation) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
        alarmManager.setExactAndAllowWhileIdle(type, triggerAtMillis, operation);
    } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
        alarmManager.setExact(type, triggerAtMillis, operation);
    } else {
        alarmManager.set(type, triggerAtMillis, operation);
    }
}

Le mode API23 + Doze interfère avec AlarmManager

Android 6 (API23) a introduit le mode Doze qui interfère avec AlarmManager. Il utilise certaines fenêtres de maintenance pour gérer les alarmes. Même si vous avez utilisé setExactAndAllowWhileIdle() vous ne pouvez pas vous assurer que votre alarme se déclenche au moment voulu.

Vous pouvez désactiver ce comportement pour votre application en utilisant les paramètres de votre téléphone ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations ou similaire)

Dans votre application, vous pouvez vérifier ce paramètre ...

String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm.isIgnoringBatteryOptimizations(packageName)) {
   // your app is ignoring Doze battery optimization
}

... et éventuellement afficher la boîte de dialogue des paramètres respectifs:

Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow