Android
AlarmManager
Suche…
Führen Sie eine Absicht später aus
- Erstellen Sie einen Empfänger. Diese Klasse erhält die Absicht und behandelt sie wie gewünscht.
public class AlarmReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
// Handle intent
int reqCode = intent.getExtras().getInt("requestCode");
...
}
}
- Weisen Sie AlarmManager eine Absicht zu. In diesem Beispiel wird die Absicht ausgelöst, dass sie nach 1 Minute an AlarmReceiver gesendet wird.
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 );
So löschen Sie einen Alarm
Wenn Sie einen Alarm abbrechen möchten und keinen Verweis auf das ursprüngliche PendingIntent haben, das zum Einstellen des Alarms verwendet wurde, müssen Sie ein PendingIntent genau so erstellen, wie es bei seiner ursprünglichen Erstellung vorlag.
Eine Absicht wird vom AlarmManager als gleich betrachtet :
wenn ihre Aktion, Daten, Typ, Klasse und Kategorien gleich sind. Dies vergleicht keine zusätzlichen Daten, die in den Absichten enthalten sind.
Normalerweise ist der Anforderungscode für jeden Alarm als eine Konstante definiert:
public static final int requestCode = 9999;
Also für einen einfachen Alarm wie folgt einrichten:
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);
So erstellen Sie eine neue PendingIntent-Referenz, mit der Sie den Alarm mit einer neuen AlarmManager-Referenz abbrechen können:
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);
}
Erstellen Sie genaue Alarme für alle Android-Versionen
Da mit der Zeit immer mehr Batterieoptimierungen in das Android-System AlarmManager
haben sich auch die Methoden des AlarmManager
erheblich geändert (um ein milderes Timing zu ermöglichen). Für einige Anwendungen ist es jedoch erforderlich, auf allen Android-Versionen so genau wie möglich zu sein. Der folgende Helper verwendet die genaueste Methode, die auf allen Plattformen verfügbar ist, um ein 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);
}
}
Der API23 + Doze-Modus greift in AlarmManager ein
Android 6 (API23) hat den Doze-Modus eingeführt, der den AlarmManager stört. Es verwendet bestimmte Wartungsfenster, um Alarme zu behandeln. Wenn Sie also setExactAndAllowWhileIdle()
, können Sie nicht sicherstellen, dass Ihr Alarm zum gewünschten Zeitpunkt ausgelöst wird.
Sie können dieses Verhalten für Ihre App mithilfe der Einstellungen Ihres Telefons deaktivieren ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations
oder ähnliches).
In Ihrer App können Sie diese Einstellung überprüfen ...
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm.isIgnoringBatteryOptimizations(packageName)) {
// your app is ignoring Doze battery optimization
}
... und zeigen ggf. den jeweiligen Einstellungsdialog:
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);