Android: настройка периодической тревоги с AlarmManager


1

В моем приложении мне нужно добавить строку в базу данных и одновременно настроить событие тревоги, чтобы повторять каждый день в то время, указанное в одном из столбцов базы данных. У меня уже есть код, но он вызывает запуск события тревоги в указанное время. Вот мой код:

public class Add_reminder extends Activity { 
    AlarmManager am; 
    int hours, minutes; 
    REMIND_DB db; 
    Calendar calendar; 
    Cursor cursor; 
    Button button; 

    public void onCreate(Bundle savedInstanceState) { 
     //The usual code in the beginning of onCreate 

     //I load db from extended Application class as global since i use it in more 
     //Activities. Ints hours and minutes is set by user interaction 

     calendar = Calendar.getInstance(); 
     am = (AlarmManager) getSystemService(ALARM_SERVICE); 

     button.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       db.open(); 
       db.insertReminder(-- parameters for database --); 
       cursor = db.getAllReminders(); 
       cursor.moveToLast(); 
       calendar.set(Calendar.HOUR, hours); 
       calendar.set(Calendar.MINUTE, minutes); 
       Intent intent = new Intent(Add_reminder.this, ReminderAlarm.class); 
       intent.putExtra("id_of_db_row", cursor.getInt(0)); 
       PendingIntent pi = PendingIntent.getActivity(Add_reminder.this, 
        cursor.getInt(0), intent, PendingIntent.FLAG_CANCEL_CURRENT); 
       am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 
        24*3600*1000, pi); 
       db.close() 
      } 
     }); 
    } 
} 

База данных обновляется правильно, но ReminderActivity никогда не запускается в указанное время. Я не знаю, что может быть неправильно. Я видел несколько примеров кода, использующих BroadcastReceiver, вместо того, чтобы начать действие с помощью PendingIntent, но это тоже должно работать, правильно? Кто-нибудь знает, что может быть неправильным?

Мой второй вопрос: если мне понадобится тот же экземпляр AlarmManager, когда я хочу добавить или удалить некоторые аварийные сигналы из другого Activity, или я просто объявляю еще один AlarmManager в каждой операции, в которой я нуждаюсь?

Спасибо!

1

Вы должны использовать широковещательный приемник для аварийных сигналов, а затем запустить службу, которая выполняет фактическую работу. Приемники широковещательной передачи не должны блокировать поток пользовательского интерфейса с длительными операциями (такими как запись в БД). Кроме того, тревога «один раз в день» может быть проблематичной: если пользователь перезагрузит телефон: зарегистрированные аварийные сигналы будут потеряны. Вам нужно:

  • экономии времени сигнал предполагается запустить, скажем, SharedPreferecnes
  • повторно зарегистрировать сигнал тревоги, когда телефон загружается (получить трансляцию BOOT_COMPLETED)
  • не используют setRepeating() но каждый регистр тревоги регистрируется следующим:

Использование более короткого периода (1 или 2 минуты) для тестирования также помогает.

Что касается экземпляра AlarmManager, это системный сервис, вам не нужно заботиться о том, какой экземпляр вы используете. Просто используйте его getSystemService()

  0

Когда я посмотрел на свой телефон этим утром, я заметил, что началось задание! Кажется, что проблема была в том, что я установил для нее (вместо использования HOUR_OF_DAY для 24-формата, я использовал HOUR для 12-формата, поэтому напоминание напомнило себя через 12 часов). У меня есть блок кода в моем основном действии, который выполняется только один раз после запуска активности. Могу ли я перерегистрировать свои тревоги там, используя данные из базы данных? Будет ли он заменять мои сигналы тревоги в случае, если пользователь только перезапустил приложение, а не сам телефон? Или это просто дублирует. Спасибо. 02 апр. 122012-04-02 07:10:08

  0

Прогресс :) Тем не менее, как правило, это плохая идея, когда из ниоткуда появляются действия. Как я уже сказал, используйте широковещательный приемник и службу. Если вам требуется взаимодействие с пользователем, отправьте уведомление и дайте возможность пользователю начать работу. Если вы используете эквивалент 'PendingIntent', то тревоги будут перезаписаны, а не дублируются. 02 апр. 122012-04-02 07:22:31

  0

Огромная помощь, спасибо :) Я буду использовать BroadcastReceiver, как вы сказали, эта проблема времени была просто более быстрой :) 02 апр. 122012-04-02 07:41:22

  0

почему бы не использовать setRepeating? на BOOT_COMPLETED будет установлен будильник, после чего он будет периодически повторяться. 05 фев. 162016-02-05 10:11:28