Sök…


Kör en avsikt vid ett senare tillfälle

  1. Skapa en mottagare. Denna klass kommer att få avsikten och hantera det hur du vill.
public class AlarmReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Handle intent
        int reqCode = intent.getExtras().getInt("requestCode");
        ...
    }
}
  1. Ge en avsikt till AlarmManager. Detta exempel utlöser avsikten att skickas till AlarmReceiver efter 1 minut.
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 );

Hur du avbryter ett larm

Om du vill avbryta ett larm och inte har en referens till det ursprungliga PendingIntent som användes för att ställa in larmet, måste du återskapa ett PendingIntent exakt som det var när det ursprungligen skapades.

En avsikt anses vara lika av AlarmManager :

om deras handling, data, typ, klass och kategorier är desamma. Detta jämför inte några extra data som ingår i avsikten.

Vanligtvis definieras förfrågningskoden för varje larm som en konstant:

public static final int requestCode = 9999;

Så för ett enkelt larm som ställts in så här:

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

Så här skapar du en ny PendingIntent-referens som du kan använda för att avbryta larmet med en ny AlarmManager-referens:

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

Skapa exakta larm i alla Android-versioner

Med fler och fler batterioptimeringar som läggs in i Android-systemet över tid har AlarmManager också förändrats avsevärt (för att möjliggöra en lättare timing). För vissa applikationer krävs det fortfarande att vara så exakt som möjligt i alla Android-versioner. Följande hjälper använder den mest exakta metoden som är tillgänglig på alla plattformar för att schemalägga en 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);
    }
}

API23 + Doze-läge stör AlarmManager

Android 6 (API23) introducerade Doze-läge som stör AlarmManager. Det använder vissa underhållsfönster för att hantera larm, så även om du använde setExactAndAllowWhileIdle() du inte se till att ditt larm avfyras vid önskad tidpunkt.

Du kan stänga av detta beteende för din app med telefonens inställningar ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations eller liknande)

Inuti din app kan du kontrollera den här inställningen ...

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

... och så småningom visa respektive inställningsdialogruta:

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow