Szukaj…


Uruchom zamiar w późniejszym czasie

  1. Utwórz odbiornik. Ta klasa otrzyma zamiar i zajmie się nim tak, jak chcesz.
public class AlarmReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Handle intent
        int reqCode = intent.getExtras().getInt("requestCode");
        ...
    }
}
  1. Podaj zamiar AlarmManager. Ten przykład wyzwoli zamiar wysłania do AlarmReceiver po 1 minucie.
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 );

Jak anulować alarm

Jeśli chcesz anulować alarm i nie masz odniesienia do oryginalnego PendingIntent użytego do ustawienia alarmu, musisz odtworzyć PendingIntent dokładnie tak, jak to było w momencie jego utworzenia.

Zamiarem jest uważany przez AlarmManager za równy :

jeśli ich działanie, dane, typ, klasa i kategorie są takie same. To nie porównuje żadnych dodatkowych danych zawartych w zamiarach.

Zwykle kod żądania dla każdego alarmu jest definiowany jako stała:

public static final int requestCode = 9999;

Tak więc, dla prostej konfiguracji alarmu takiej jak ta:

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

Oto, jak utworzyć nowe odwołanie PendingIntent, którego można użyć do anulowania alarmu za pomocą nowego odwołania 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);
}

Tworzenie dokładnych alarmów we wszystkich wersjach Androida

Wraz z upływem czasu coraz więcej optymalizacji baterii w systemie Android, metody AlarmManager również uległy znacznej zmianie (aby umożliwić bardziej łagodny czas). Jednak w przypadku niektórych aplikacji nadal musi być możliwie jak najdokładniejszy we wszystkich wersjach Androida. Następujący pomocnik używa najdokładniejszej metody dostępnej na wszystkich platformach do planowania 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);
    }
}

Tryb API23 + Tryb drzemki zakłóca działanie AlarmManager

Android 6 (API23) wprowadził tryb Doze, który zakłóca działanie AlarmManager. Do obsługi alarmów używa pewnych okien serwisowych, więc nawet jeśli użyłeś setExactAndAllowWhileIdle() , nie możesz upewnić się, że twój alarm uruchomi się w żądanym momencie.

Możesz wyłączyć to zachowanie dla swojej aplikacji za pomocą ustawień telefonu ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations lub podobne)

W aplikacji możesz sprawdzić to ustawienie ...

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

... i ostatecznie pokaż odpowiednie okno dialogowe ustawień:

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow