Android
AlarmManager
Zoeken…
Voer een intentie op een later tijdstip uit
- Maak een ontvanger. Deze klas zal de intentie ontvangen en ermee omgaan zoals jij dat wilt.
public class AlarmReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
// Handle intent
int reqCode = intent.getExtras().getInt("requestCode");
...
}
}
- Geef een intentie aan AlarmManager. Dit voorbeeld activeert de intentie om na 1 minuut naar AlarmReceiver te worden verzonden.
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 );
Een alarm annuleren
Als u een alarm wilt annuleren en u hebt geen verwijzing naar de oorspronkelijke PendingIntent die is gebruikt om het alarm in te stellen, moet u een PendingIntent opnieuw maken precies zoals het was toen het oorspronkelijk werd gemaakt.
Een intentie wordt door de AlarmManager als gelijk beschouwd :
als hun actie, gegevens, type, klasse en categorieën hetzelfde zijn. Dit vergelijkt geen extra gegevens die in de intenties zijn opgenomen.
Gewoonlijk wordt de aanvraagcode voor elk alarm gedefinieerd als een constante:
public static final int requestCode = 9999;
Dus, voor een eenvoudig alarm zoals dit:
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);
Hier ziet u hoe u een nieuwe PendingIntent-referentie kunt maken die u kunt gebruiken om het alarm te annuleren met een nieuwe AlarmManager-referentie:
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);
}
Exacte alarmen maken op alle Android-versies
Met steeds meer batterij-optimalisaties die in de loop van de tijd in het Android-systeem worden geplaatst, zijn de methoden van de AlarmManager
ook aanzienlijk veranderd (om een soepelere timing mogelijk te maken). Voor sommige applicaties moet het echter nog steeds zo nauwkeurig mogelijk zijn op alle Android-versies. De volgende helper gebruikt de meest nauwkeurige methode die beschikbaar is op alle platforms om een PendingIntent
te plannen:
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);
}
}
API23 + Doze-modus interfereert met AlarmManager
Android 6 (API23) heeft de Doze-modus geïntroduceerd die interfereert met AlarmManager. Het gebruikt bepaalde onderhoudsvensters om alarmen af te handelen, dus zelfs als u setExactAndAllowWhileIdle()
hebt gebruikt, kunt u er niet voor zorgen dat uw alarm op het gewenste tijdstip afgaat.
U kunt dit gedrag voor uw app uitschakelen met behulp van de instellingen van uw telefoon ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations
of iets dergelijks)
In uw app kunt u deze instelling controleren ...
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm.isIgnoringBatteryOptimizations(packageName)) {
// your app is ignoring Doze battery optimization
}
... en uiteindelijk het bijbehorende instellingendialoogvenster weergeven:
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);