Ricerca…


Esegui un intento in un secondo momento

  1. Crea un ricevitore. Questa classe riceverà l'intento e gestirà come desideri.
public class AlarmReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Handle intent
        int reqCode = intent.getExtras().getInt("requestCode");
        ...
    }
}
  1. Dare un intento a AlarmManager. Questo esempio attiverà l'intenzione di essere inviata ad AlarmReceiver dopo 1 minuto.
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 );

Come annullare un allarme

Se si desidera annullare un allarme e non si dispone di un riferimento al PendingIntent originale utilizzato per impostare l'allarme, è necessario ricreare un PendingIntent esattamente com'era quando è stato originariamente creato.

Un intento è considerato uguale da AlarmManager :

se la loro azione, i dati, il tipo, la classe e le categorie sono gli stessi. Questo non confronta alcun dato extra incluso negli intenti.

Di solito il codice di richiesta per ogni allarme è definito come una costante:

public static final int requestCode = 9999;

Quindi, per un semplice allarme impostato in questo modo:

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

Ecco come si creerebbe un nuovo riferimento PendingIntent che è possibile utilizzare per annullare l'allarme con un nuovo riferimento 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);
}

Creazione di allarmi esatti su tutte le versioni di Android

Con l'aumentare del numero di ottimizzazioni della batteria nel sistema Android nel tempo, anche i metodi di AlarmManager sono stati modificati in modo significativo (per consentire tempi più lievi). Tuttavia, per alcune applicazioni è ancora necessario essere il più precisi possibile su tutte le versioni di Android. Il seguente helper utilizza il metodo più accurato disponibile su tutte le piattaforme per pianificare 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);
    }
}

La modalità API2 + Doze interferisce con AlarmManager

Android 6 (API23) ha introdotto la modalità Doze che interferisce con AlarmManager. Usa determinate finestre di manutenzione per gestire gli allarmi, quindi anche se hai usato setExactAndAllowWhileIdle() non puoi fare in modo che il tuo allarme si setExactAndAllowWhileIdle() nel momento desiderato.

È possibile disattivare questo comportamento per l'app utilizzando le impostazioni del telefono ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations o simili)

All'interno della tua app puoi controllare questa impostazione ...

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

... e alla fine mostra la rispettiva finestra di dialogo delle impostazioni:

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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow