Настройка диспетчера тревог в Android

Я слежу за документацией разработчиков Android и некоторыми другими трюками, чтобы создать диспетчер аварийных сигналов, который запускает и будит процессор в 16:00 каждый день, следующий мой код:

    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    BroadcastReceiver br;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    // Set the alarm to start at approximately 2:00 p.m.
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 16);
    alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, alarmIntent);
}


public void setup() {
    br = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent i) {
            Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
            //Invoke the service here Put the wake lock and initiate bind service

        }
    };
    registerReceiver(br, new IntentFilter("com.testrtc") );
    alarmIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.testrtc"),
            0 );
    alarmMgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}

}

Манифест:

   <uses-permission android:name="android.permission.WAKE_LOCK" />

Однако я не получаю никаких ошибок, но сигнал тревоги (тостовое сообщение) не срабатывает.

ИЗМЕНИТЬ из документации для разработчиков:

Примеры RTC

Вот несколько примеров использования RTC_WAKEUP.

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

// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

Этот для установки Повторение говорит, что если я хочу, чтобы мой будильник срабатывал в 8:30, а затем повторялся через каждые 20 минут, однако я просто хочу активировать свой будильник в определенное время, но я не хочу его повторять.

Выведите устройство из режима сна ровно в 8:30 утра, а затем каждые 20 минут:

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);

person User3    schedule 20.01.2014    source источник
comment
вы хотите включить пожарную тревогу в точное время, тогда почему вы используете setInexactRepeating? просто используйте setRepeating, и все готово. просто.   -  person Mehul Joisar    schedule 20.01.2014
comment
Хотя я понимаю, что то, что вы говорите, имеет смысл, но, тем не менее, документы разработчика, похоже, меня сбивают с толку. См. Раздел редактирования в моем вопросе выше.   -  person User3    schedule 20.01.2014
comment
Я опубликовал ответ с кодом решения и объяснением, почему вам не следует использовать setInexactRepeating.   -  person Mehul Joisar    schedule 20.01.2014


Ответы (6)


Решите, насколько точным должен быть будильник

Выбор типа сигнала тревоги часто является первым шагом в создании сигнала тревоги. Еще одно различие заключается в том, насколько точным должен быть ваш будильник. Для большинства приложений setInexactRepeating() - правильный выбор. При использовании этого метода Android синхронизирует несколько неточно повторяющихся сигналов тревоги и активирует их одновременно. Это снижает расход заряда батареи.

Для редкого приложения, которое имеет жесткие временные ограничения, как ваше, будильник должен срабатывать точно в 16:00. каждый день используйте setRepeating().

Ссылка: Решите, насколько точным должен быть ваш будильник

Solution :

    alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// Set the alarm to start at approximately 4:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 16);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000*60*60*24, alarmIntent);

Отредактированное тестирование: (Fire alarm at every 10seconds)

        alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(),
        1000*10, alarmIntent);

Вывод:

setup() метод не был вызван перед обработкой сигналов тревоги.


Обновление для API 19+

setRepeating является неточным при ориентации на API уровня 19 или выше. Для точного повторения теперь вы можете использовать setExact() и управлять повторением самого себя.

ссылка: документация по AlarmManager

person Mehul Joisar    schedule 20.01.2014
comment
@ user2822178: он будет отображаться только в 16:00. Пожалуйста, измените время для целей тестирования. - person Mehul Joisar; 20.01.2014
comment
Да, я тоже изменил время, поставил на 17:15 IST - person User3; 20.01.2014
comment
@ user2822178: Я добавил тестовый пример, попробуйте. - person Mehul Joisar; 20.01.2014
comment
Не стреляет даже после десятисекундного интервала. (Дергает меня за волосы) - person User3; 20.01.2014
comment
@ user2822178: успокойся и верь ;-). попробуйте отредактированный тестовый код, дайте мне знать, работает ли он для вас - person Mehul Joisar; 20.01.2014
comment
Пробовал выше, не работает; - person User3; 20.01.2014
comment
@ user2822178: Я почти уверен, что проблема не в диспетчере сигналов тревоги, вы что-то напутали где-то еще. потому что эти коды работают для моих существующих приложений - person Mehul Joisar; 20.01.2014
comment
позвольте нам продолжить обсуждение в чате - person User3; 20.01.2014
comment
обновите, пожалуйста, свой ответ, установите Поведение повторения изменено с помощью API 19 - person cuddlecheek; 19.08.2016

Вместо использования setInexactRepeating() я предлагаю вам использовать setRepeating()

из документов,

setInexactRepeating (тип int, long triggerAtMillis, long intervalMillis, операция PendingIntent)

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

setRepeating (тип int, long triggerAtMillis, long intervalMillis, операция PendingIntent)

  • Запланируйте повторяющийся будильник.
person Vigbyor    schedule 20.01.2014
comment
Я так думаю, что планирование повторяющегося будильника предназначено для интервалов после завершения загрузки? Также, если это необходимо повторить через некоторый интервал, developer.android.com/training/scheduling/ alarms.html - person User3; 20.01.2014
comment
Итак, вы хотите, чтобы сигнал тревоги сохранялся даже после загрузки устройства? - person Vigbyor; 20.01.2014
comment
Да, я хочу сохранить сигнал тревоги, который я собираюсь сделать после вызова прослушивателя завершения загрузки. Однако для этого сначала должна сработать сигнализация. Также меня беспокоит то, что нужно ли мне явно получать блокировку пробуждения, или RTC будет делать это за меня? - person User3; 20.01.2014
comment
Нет, мой вопрос не в загрузке и сохранении будильника, вместо этого мой вопрос в том, что мой будильник не срабатывает. Without considering Boot - person User3; 20.01.2014
comment
так он ни разу не стреляет? - person Vigbyor; 20.01.2014
comment
давайте продолжим обсуждение в чате - person Vigbyor; 20.01.2014
comment
Нет, я тестирую MaxSDK = 18 и использую JellyBean на тестовом устройстве. - person User3; 20.01.2014
comment
@Tobor, пока вы рядом, но OP не упомянул, что он / она использует версию Kitkat или нет. - person Vigbyor; 20.01.2014

Документация довольно ясна:

public void setInexactRepeating (...)

triggerAtMill - время в миллисекундах, в течение которого будильник должен сработать первым, с использованием соответствующих часов (в зависимости от типа будильника). Это неточно: тревога не сработает до этого времени, но может быть задержка почти на весь интервал тревоги перед первым вызовом тревоги.

поэтому, насколько я понимаю, но может быть задержка почти на весь интервал будильника означает, что у вас может быть задержка на один день, потому что вы используете AlarmManager.INTERVAL_DAY.

person marcinj    schedule 20.01.2014
comment
И как мне это преодолеть? Я не могу позволить себе активировать этот будильник на следующий день! - person User3; 20.01.2014
comment
вы можете изменить значение на INTERVAL_FIFTEEN_MINUTES, вы, по крайней мере, увидите, является ли это причиной вашей проблемы - сигнал тревоги должен сработать примерно через 15 минут. - person marcinj; 20.01.2014
comment
Документация по Alarm Manager настолько скудна !! - person User3; 20.01.2014

установите минуты и секунды также в календарь ..

 calendar.set(Calendar.HOUR, 16); // At the hour you wanna fire
 calendar.set(Calendar.MINUTE, 0); // Particular minute
 calendar.set(Calendar.SECOND, 0); 

и использовать

  alarmManager.setRepeating(AlarmManager.RTC,
        calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
        alarmIntent);  
person priyanka morisetti    schedule 20.01.2014

У меня была такая же проблема (обычно это проблема Huawei), и я решил, включив приложение в PowerManager или Protected Apps.

person Manza    schedule 09.12.2015

Попробуйте создать приемник, расширяющий WakefulBroadcastReceiver:

public class MyReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        Intent myService = new Intent(context, MyService.class);
        context.startService(myService);
    }
}

В свою службу вы можете поставить тост или попробовать записать журнал в файл, чтобы убедиться, что он работает. Затем в вашей деятельности:

       Intent myAlarm = new Intent(context.getApplicationContext(), MyReceiver.class);
       PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
       AlarmManager alarms = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
       alarms.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), 4 * 1000 * 60, recurringAlarm); 

// Будильник каждые 4 минуты

person Meriam    schedule 22.06.2017