Подтвердить что ты не робот

Как настроить повторяющийся AlarmManager для ежедневного выполнения кода

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

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

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

4b9b3361

Ответ 1

Я обычно делаю что-то большее по строкам:

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 и используя AlarmManager, которое основано на моем собственном опыте и нескольких советах и ​​трюках, которые я снял, наблюдая за разговорами ввода-вывода Google. Если вам интересно, вы можете прочитать его здесь.


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

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

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

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

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

Ответ 2

Это работает, это будет снимать сигнал тревоги каждые 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.
    }