Android: как использовать AlarmManager


89

Мне нужно запустить блок кода через 20 минут после AlarmManagerустановки.

Может ли кто-нибудь показать мне пример кода, как использовать AlarmManagerв ِ Android?

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

Ответы:


109

Когда дело доходит до "Образца кода", не так-то просто AlarmManager.

Вот фрагмент, показывающий настройку AlarmManager:

AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);

mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);

В этом примере я использую setRepeating(). Если вам нужен одноразовый будильник, вы просто используете set(). Убедитесь, что время срабатывания будильника задано на той же временной основе, что и в исходном параметре set(). В моем примере выше я использую AlarmManager.ELAPSED_REALTIME_WAKEUP, поэтому моя временная база SystemClock.elapsedRealtime().

Вот более крупный пример проекта, демонстрирующий эту технику.


2
И снова здравствуйте. Спасибо за ответ. Если я куплю вашу книгу, в ней подробно объясняется, как реализовать диспетчер аварийных сигналов?
Tom

7
В книге Advanced Android (версия 0.9) есть ~ 9 страниц, посвященных AlarmManager, WakeLocks и остальной части этого примера. Вероятно, это немного расширится в версии 1.0, когда я внесу исправление, о котором упоминал в своем ответе выше. А если у вас есть вопросы относительно книги или ее примера кода, перейдите на groups.google.com/group/cw-android, и я с радостью на них отвечу.
CommonsWare,

17
Любой разработчик Android должен иметь подписку на книги Марка :) Хотя бы один раз
Bostone

1
@ MarioGalván: вам нужно установить его, когда ваше приложение запускается в первый раз и при перезагрузке.
CommonsWare

Я думаю, вам следует использовать AlarmManager.RTC_WAKEUP, если вы хотите, чтобы он запускался сразу, а затем каждый ПЕРИОД. В вашем коде он будет срабатывать после SystemClock.elapsedRealtime (), а затем каждый PERIOD.
Дэймон Юань

66

В образце кода Android есть несколько хороших примеров

. \ android-sdk \ samples \ android-10 \ ApiDemos \ src \ com \ example \ android \ apis \ app

Стоит проверить:

  • AlarmController.java
  • OneShotAlarm.java

Во-первых, вам нужен приемник, который может прослушивать ваш будильник, когда он срабатывает. Добавьте в файл AndroidManifest.xml следующее:

<receiver android:name=".MyAlarmReceiver" />

Затем создайте следующий класс

public class MyAlarmReceiver extends BroadcastReceiver { 
     @Override
     public void onReceive(Context context, Intent intent) {
         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

Затем, чтобы вызвать тревогу, используйте следующее (например, в своем основном действии):

AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 30);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);

.


Или, еще лучше, создайте класс, который обрабатывает все это, и используйте его так

Bundle bundle = new Bundle();
// add extras here..
MyAlarm alarm = new MyAlarm(this, bundle, 30);

Таким образом, у вас есть все в одном месте (не забудьте отредактировать AndroidManifest.xml)

public class MyAlarm extends BroadcastReceiver {
    private final String REMINDER_BUNDLE = "MyReminderBundle"; 

    // this constructor is called by the alarm manager.
    public MyAlarm(){ }

    // you can use this constructor to create the alarm. 
    //  Just pass in the main activity as the context, 
    //  any extras you'd like to get later when triggered 
    //  and the timeout
     public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
         AlarmManager alarmMgr = 
             (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent intent = new Intent(context, MyAlarm.class);
         intent.putExtra(REMINDER_BUNDLE, extras);
         PendingIntent pendingIntent =
             PendingIntent.getBroadcast(context, 0, intent, 
             PendingIntent.FLAG_UPDATE_CURRENT);
         Calendar time = Calendar.getInstance();
         time.setTimeInMillis(System.currentTimeMillis());
         time.add(Calendar.SECOND, timeoutInSeconds);
         alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                      pendingIntent);
     }

      @Override
     public void onReceive(Context context, Intent intent) {
         // here you can get the extras you passed in when creating the alarm
         //intent.getBundleExtra(REMINDER_BUNDLE));

         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

2
Всем привет! Я протестировал этот код, и он отлично работает (+1). но я пробовал это для нескольких сигналов тревоги (например, один на 10 секунд, а другой на 15, и срабатывает только один второй. Я что-то делаю неправильно, или это какая-то проблема? РЕДАКТИРОВАТЬ: Хорошо, я нашел проблему здесь : stackoverflow.com/questions/2844274/…
Нуно Гонсалвес,

FWIW, я бы использовал для этого статический метод, а не конструктор.
Эдвард Фальк

9

Что вам нужно сделать, это сначала создать намерение, которое вам нужно запланировать. Затем получите pendingIntent этого намерения. Вы можете запланировать мероприятия, услуги и трансляции. Чтобы запланировать мероприятие, например MyActivity:

  Intent i = new Intent(getApplicationContext(), MyActivity.class);
  PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
  PendingIntent.FLAG_CANCEL_CURRENT);

Передайте это pendingIntent в alarmManager:

  //getting current time and add 5 seconds in it
  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.SECOND, 5);
  //registering our pending intent with alarmmanager
  AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
  am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);

Теперь MyActivity будет запущен через 5 секунд после запуска приложения, независимо от того, остановили ли вы приложение или устройство перешло в спящий режим (из-за опции RTC_WAKEUP). Вы можете прочитать полный пример кода. Планирование действий, услуг и трансляций #Android


+1 отличный ответ, именно то, что мне нужно, рабочий пример «набора».
A.Alqadomi

4

Я хотел прокомментировать, но <50 респондентов, так что приступим. Дружеское напоминание о том, что если вы работаете на версии 5.1 или выше и используете интервал менее минуты, произойдет следующее:

Suspiciously short interval 5000 millis; expanding to 60 seconds

Смотрите здесь .


3

Пример кода, если вы хотите вызвать службу из Alarmmanager:

PendingIntent pi;
AlarmManager mgr;
mgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(DataCollectionActivity.this, HUJIDataCollectionService.class);    
pi = PendingIntent.getService(DataCollectionActivity.this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , 1000, pi);

Вам не нужно спрашивать разрешения пользователя.


Очень распространенное сокращение.
Phantômaxx

0

AlarmManager используется для запуска некоторого кода в определенное время.

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

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent alarmIntent = new Intent(context, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
int interval = 8000; //repeat interval
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);

Будьте осторожны при использовании Alarm Manager. Обычно диспетчер сигналов тревоги не может повториться раньше, чем через минуту. Также в режиме низкого энергопотребления продолжительность может увеличиваться до 15 минут.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.