Поиск…


Запустите намерение позднее

  1. Создайте приемник. Этот класс получит намерение и обработает его, как вы пожелаете.
public class AlarmReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Handle intent
        int reqCode = intent.getExtras().getInt("requestCode");
        ...
    }
}
  1. Дайте намерение AlarmManager. Этот пример вызовет намерение отправляться в AlarmReceiver через 1 минуту.
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 );

Как отменить будильник

Если вы хотите отменить будильник, и у вас нет ссылки на исходный PendingIntent, используемый для установки будильника, вам нужно воссоздать PendingIntent точно так, как это было, когда оно было изначально создано.

Настройщик считается равным с помощью AlarmManager :

если их действие, данные, тип, класс и категории одинаковы. Это не сравнивает никаких дополнительных данных, включенных в намерения.

Обычно код запроса для каждого аварийного сигнала определяется как константа:

public static final int requestCode = 9999;

Итак, для простой тревоги, настроенной так:

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

Вот как вы создадите новую ссылку PendingIntent, которую вы можете использовать для отмены тревоги с помощью новой ссылки 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);
}

Создание точных сигналов тревоги на всех версиях Android

С течением времени в систему Android все больше и больше оптимизируются батареи, методы AlarmManager также значительно изменились (чтобы обеспечить более мягкое время). Однако для некоторых приложений по-прежнему необходимо быть как можно более точным на всех версиях Android. Следующий помощник использует самый точный метод, доступный на всех платформах для планирования 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 вмешивается в AlarmManager

Android 6 (API23) представил режим Doze, который мешает AlarmManager. Он использует определенные окна обслуживания для обработки аварийных сигналов, поэтому, даже если вы использовали setExactAndAllowWhileIdle() вы не можете убедиться, что ваш будильник срабатывает в нужный момент времени.

Вы можете отключить это поведение для своего приложения, используя настройки вашего телефона ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations или подобное)

Внутри приложения вы можете проверить этот параметр ...

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

... и в итоге отобразите соответствующий диалог настроек:

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow