Как установить Recurring AlarmManager для ежедневного выполнения кода - PullRequest
17 голосов
/ 13 декабря 2010

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

      if ((User.getReminderTime(Home.this) > 0)
    && (dt.getDate() != today.getDate() || dt.getDay() != today
      .getDay())) {
   AppointmentManager.setFutureAppointmentCheck(this
     .getApplicationContext());
   User.setLongSetting(this, "futureappts", today.getTime());
  }

Затем я иду и устанавливаю фактическую тревогу, чтобы она сработала между 12 и 12:10 следующего дня:

     public static void setFutureAppointmentCheck(Context con) {
  AlarmManager am = (AlarmManager) con
    .getSystemService(Context.ALARM_SERVICE);

  Date futureDate = new Date(new Date().getTime() + 86400000);
  Random generator = new Random();

  futureDate.setHours(0);
  futureDate.setMinutes(generator.nextInt(10));
  futureDate.setSeconds(0);

  Intent intent = new Intent(con, FutureAppointmentReciever.class);

  PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent,
    PendingIntent.FLAG_ONE_SHOT);

  am.set(AlarmManager.RTC_WAKEUP, futureDate.getTime(), sender);

 }

Теперь я настраиваю тестовую среду, чтобы она отключалась каждые две минуты, и, кажется, она работает нормально, однако при развертывании на реальном устройстве приемник, похоже, не получает сигналы тревоги.,Я подумал, что это может быть проблема с устройством, спящим, поэтому я добавил диспетчер питания.Но это все равно не работает:

      PowerManager pm = (PowerManager) context
    .getSystemService(Context.POWER_SERVICE);
  PowerManager.WakeLock wl = pm.newWakeLock(
    PowerManager.PARTIAL_WAKE_LOCK, "keepAlive");
  wl.acquire();
  setFutureAppointments(context.getApplicationContext());
  AppointmentManager.setFutureAppointmentCheck(context
    .getApplicationContext());
  User.setLongSetting(context.getApplicationContext(), "futureappts",
    new Date().getTime());
  wl.release();

Кто-нибудь видит что-то, что я делаю явно неправильно, или я поступаю неправильно?спасибо за любую помощь.

Ответы [ 2 ]

44 голосов
/ 13 декабря 2010

Я обычно делаю что-то более похожее на:

Intent i = new Intent(this, MyService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.cancel(pi); // cancel any existing alarms
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
    SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
    AlarmManager.INTERVAL_DAY, pi);

Таким образом, вам не нужно беспокоиться о переустановке AlarmManager в вашем Service.

Я обычно запускаю этот бит кода, когда мое приложение запускается (onResume в моей основной деятельности) и в BroadcastReceiver, настроенном на получение BOOT_COMPLETED.

Я написал руководствоо создании Service s и использовании AlarmManager, основанном на моем собственном опыте и нескольких советах и ​​уловках, которые я выбрал при просмотре речи ввода-вывода Google.Если вам интересно, вы можете прочитать это здесь .


Чтобы ответить на ваш вопрос ниже, все, что я могу сделать, это процитировать документы :

public void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)

Расписание повторяющегося сигнала тревоги, который имеет неточные требования ко времени запуска;например, сигнал тревоги, который повторяется каждый час, но не обязательно в начале каждого часа.Эти аварийные сигналы более энергоэффективны, чем строгие повторения, предоставляемые setRepeating (int, long, long, PendingIntent), поскольку система может регулировать фазу аварийных сигналов, чтобы они срабатывали одновременно, избегая более полного выхода устройства из спящего режима.

Первый триггер вашего будильника не будет раньше запрошенного времени, но он может не срабатывать в течение почти полного интервала после этого времени.Кроме того, хотя общий период повторяющейся тревоги будет соответствовать запросу, время между любыми двумя последовательными срабатываниями тревоги может варьироваться.Если ваше приложение требует очень низкого дрожания, используйте вместо него setRepeating (int, long, long, PendingIntent).

В заключение, это не очень понятно.В документах только сказано, что будильник «может отличаться».Однако вам важно знать, что первый триггер может не срабатывать в течение почти полного интервала после этого времени .

4 голосов
/ 24 июля 2013

Это работает, будет срабатывать будильник через каждые 5 секунд

private void setRecurringAlarm() {

        Logger.d(IConstants.DEBUGTAG, "Setting Recurring Alarm");

        Calendar updateTime = Calendar.getInstance();

        updateTime.set(Calendar.SECOND, 5);

        Intent alarmIntent = new Intent(this, AlarmReceiver.class);
        PendingIntent recurringDownload = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarms.cancel(recurringDownload);
        alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 1000 * 5, recurringDownload); //will run it after every 5 seconds.
    }
...