AlarmManager
) дают вам возможность выполнять операции, основанные на времени, за пределами жизненного цикла вашего приложения. Например, вы можете использовать сигнал тревоги для запуска длительной операции, например, запуска службы один раз в день для загрузки прогноза погоды.Сигнализации имеют следующие характеристики:
Они позволяют вам активировать намерения в заданное время и/или с заданными интервалами.
Их можно использовать совместно с широковещательными приемниками для планирования заданий или WorkRequests для выполнения других операций.
Они работают вне вашего приложения, поэтому вы можете использовать их для запуска событий или действий, даже когда ваше приложение не запущено, и даже если само устройство находится в спящем режиме.
Они помогают вам минимизировать требования к ресурсам вашего приложения. Вы можете планировать операции, не полагаясь на таймеры или постоянно работающие службы.
Установите неточный будильник
Когда приложение устанавливает неточный будильник , система доставит будильник в какой-то момент в будущем. Неточные будильники предоставляют некоторые гарантии относительно времени доставки будильника, соблюдая ограничения по экономии заряда батареи, такие как Doze .
Разработчики могут использовать следующие гарантии API для настройки времени доставки неточных сигналов тревоги.
Подавать сигнал тревоги через определенное время
Если ваше приложение вызывает set()
, setInexactRepeating()
или setAndAllowWhileIdle()
, будильник никогда не сработает до указанного времени срабатывания.
На устройствах с Android 12 (уровень API 31) и выше система активирует будильник в течение одного часа с указанного времени срабатывания, если не действуют какие-либо ограничения по экономии заряда батареи, такие как режим экономии заряда батареи или Doze .
Подать сигнал тревоги в течение временного окна
Если ваше приложение вызывает setWindow()
, будильник никогда не сработает до указанного времени срабатывания. Если не действуют какие-либо ограничения по экономии заряда батареи, будильник будет доставлен в указанном временном окне, начиная с указанного времени срабатывания.
Если ваше приложение предназначено для Android 12 или выше, система может отложить вызов временного окна неточного будильника как минимум на 10 минут. По этой причине значения параметра windowLengthMillis
ниже 600000
обрезаются до 600000
.
Подавать повторяющийся сигнал тревоги примерно через равные промежутки времени
Если ваше приложение вызывает setInexactRepeating()
, система вызывает несколько оповещений:
- Первый будильник срабатывает в указанном временном окне, начиная с указанного времени срабатывания.
- Последующие сигналы тревоги обычно срабатывают по истечении указанного временного окна. Время между двумя последовательными вызовами сигнала тревоги может варьироваться.
Установите точный будильник
Система активирует точный сигнал тревоги в определенный момент в будущем.
Большинство приложений могут планировать задачи и события, используя неточные сигналы тревоги для выполнения нескольких распространенных случаев использования . Если основная функциональность вашего приложения зависит от точно рассчитанного по времени сигнала тревоги, например, для приложения-будильника или приложения-календаря, то можно использовать вместо него точный сигнал тревоги.
Случаи использования, когда точные сигналы тревоги могут не потребоваться
В следующем списке показаны общие рабочие процессы, которые могут не требовать точного оповещения:
- Планирование операций по времени в течение жизненного цикла вашего приложения
- Класс
Handler
включает несколько хороших методов для обработки операций синхронизации, таких как выполнение некоторой работы каждые n секунд, пока ваше приложение активно:postAtTime()
иpostDelayed()
. Обратите внимание, что эти API полагаются на время безотказной работы системы , а не на реальное время . - Запланированная фоновая работа, например обновление приложения и загрузка журналов
-
WorkManager
предоставляет способ планирования периодической работы, чувствительной к времени . Вы можете указать интервал повторения иflexInterval
(минимум 15 минут), чтобы определить детальное время выполнения работы. - Указанное пользователем действие, которое должно произойти по истечении определенного времени (даже если система находится в состоянии ожидания)
- Используйте неточный будильник. А именно, вызовите
setAndAllowWhileIdle()
. - Указанное пользователем действие, которое должно произойти через определенное время
- Используйте неточный будильник. А именно, вызовите
set()
. - Указанное пользователем действие, которое может произойти в течение указанного временного окна
- Используйте неточный будильник. А именно, вызовите
setWindow()
. Обратите внимание, что если ваше приложение предназначено для Android 12 или выше, наименьшая допустимая длина окна составляет 10 минут.
Способы установки точного будильника
Ваше приложение может устанавливать точные сигналы тревоги, используя один из следующих методов. Эти методы упорядочены таким образом, что те, что ближе к концу списка, обслуживают более срочные задачи, но требуют больше системных ресурсов.
-
setExact()
Включайте будильник в практически точное время в будущем, если только не будут приняты другие меры по экономии заряда батареи.
Используйте этот метод для установки точных будильников, если только работа вашего приложения не является критичной для пользователя по времени.
-
setExactAndAllowWhileIdle()
Вызов будильника в практически точное время в будущем, даже если действуют меры по экономии заряда батареи.
-
setAlarmClock()
Вызовите сигнал тревоги в точное время в будущем. Поскольку эти сигналы тревоги очень хорошо видны пользователям, система никогда не корректирует время их доставки. Система определяет эти сигналы тревоги как наиболее критические и оставляет режимы низкого энергопотребления, если это необходимо для доставки сигналов тревоги.
Потребление системных ресурсов
Когда система запускает точные оповещения, которые устанавливает ваше приложение, устройство потребляет много ресурсов, таких как заряд батареи, особенно если оно находится в режиме энергосбережения. Более того, система не может легко пакетировать эти запросы, чтобы использовать ресурсы более эффективно.
Настоятельно рекомендуется создавать неточный сигнал тревоги , когда это возможно. Для выполнения более длительной работы запланируйте ее с помощью WorkManager
или JobScheduler
из BroadcastReceiver
вашего сигнала тревоги. Для выполнения работы, пока устройство находится в режиме Doze, создайте неточный сигнал тревоги с помощью setAndAllowWhileIdle()
и запустите задание из сигнала тревоги.
Объявите соответствующее точное разрешение на сигнализацию
Если ваше приложение нацелено на Android 12 или выше, вам необходимо получить специальный доступ к приложению «Будильники и напоминания». Для этого объявите разрешение SCHEDULE_EXACT_ALARM
в файле манифеста вашего приложения, как показано в следующем фрагменте кода:
<manifest ...> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
Если ваше приложение предназначено для Android 13 (уровень API 33) или выше, у вас есть возможность объявить разрешение SCHEDULE_EXACT_ALARM
или USE_EXACT_ALARM
.
<manifest ...> <uses-permission android:name="android.permission.USE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
Хотя разрешения SCHEDULE_EXACT_ALARM
и USE_EXACT_ALARM
указывают на одни и те же возможности, они предоставляются по-разному и поддерживают разные варианты использования. Ваше приложение должно использовать точные сигналы тревоги и объявлять разрешение SCHEDULE_EXACT_ALARM
или USE_EXACT_ALARM
, только если функция, обращенная к пользователю в вашем приложении, требует точно рассчитанных по времени действий.
USE_EXACT_ALARM
- Предоставляется автоматически
- Не может быть отозвано пользователем
- В соответствии с будущей политикой Google Play
- Ограниченные варианты использования
SCHEDULE_EXACT_ALARM
- Предоставлено пользователем
- Более широкий набор вариантов использования
- Приложения должны подтвердить, что разрешение не было отозвано.
Разрешение SCHEDULE_EXACT_ALARM
не предоставляется заранее для новых установок приложений, ориентированных на Android 13 (уровень API 33) и выше. Если пользователь переносит данные приложения на устройство под управлением Android 14 с помощью операции резервного копирования и восстановления, разрешение SCHEDULE_EXACT_ALARM
будет отклонено на новом устройстве. Однако, если существующее приложение уже имеет это разрешение, оно будет предоставлено заранее при обновлении устройства до Android 14.
Примечание : Если точный будильник установлен с помощью объекта OnAlarmListener
, например, с помощью API setExact
, разрешение SCHEDULE_EXACT_ALARM
не требуется.
Использование разрешения SCHEDULE_EXACT_ALARM
В отличие от USE_EXACT_ALARM
, разрешение SCHEDULE_EXACT_ALARM
должно быть предоставлено пользователем. Отозвать разрешение SCHEDULE_EXACT_ALARM
может как пользователь, так и система.
Чтобы проверить, предоставлено ли разрешение вашему приложению, вызовите canScheduleExactAlarms()
перед попыткой установить точный будильник. Когда разрешение SCHEDULE_EXACT_ALARM
отзывается для вашего приложения, ваше приложение останавливается, и все будущие точные будильники отменяются. Это также означает, что значение, возвращаемое canScheduleExactAlarms()
остается действительным в течение всего жизненного цикла вашего приложения.
Когда вашему приложению предоставлено разрешение SCHEDULE_EXACT_ALARMS
, система отправляет ему широковещательную рассылку ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
. Ваше приложение должно реализовать приемник широковещательной рассылки , который выполняет следующие действия:
- Подтверждает, что ваше приложение все еще имеет специальный доступ к приложению. Для этого вызовите
canScheduleExactAlarms()
. Эта проверка защищает ваше приложение от случая, когда пользователь предоставляет вашему приложению разрешение, а затем почти сразу же отзывает его. - Перепланирует любые точные оповещения, которые нужны вашему приложению, на основе его текущего состояния. Эта логика должна быть похожа на то, что делает ваше приложение, когда оно получает трансляцию
ACTION_BOOT_COMPLETED
.
Попросите пользователей предоставить разрешение SCHEDULE_EXACT_ALARM
При необходимости вы можете отправлять пользователей на экран «Будильники и напоминания» в настройках системы, как показано на рисунке 1. Для этого выполните следующие действия:
- В пользовательском интерфейсе вашего приложения объясните пользователю, почему вашему приложению необходимо планировать точные будильники.
- Вызовите намерение, включающее действие намерения
ACTION_REQUEST_SCHEDULE_EXACT_ALARM
.
Установите повторяющийся будильник
Повторяющиеся сигналы тревоги позволяют системе уведомлять ваше приложение по повторяющемуся графику.
Неправильно спроектированный будильник может привести к разрядке батареи и существенной нагрузке на серверы. По этой причине на Android 4.4 (уровень API 19) и выше все повторяющиеся будильники являются неточными будильниками .
Повторяющийся сигнал тревоги имеет следующие характеристики:
Тип сигнала тревоги. Для более подробного обсуждения см. Выбор типа сигнала тревоги .
Время срабатывания. Если указанное вами время срабатывания уже прошло, сигнализация срабатывает немедленно.
Интервал будильника. Например, раз в день, каждый час или каждые 5 минут.
Ожидаемое намерение, которое срабатывает при срабатывании будильника. Когда вы устанавливаете второй будильник, который использует то же самое ожидаемое намерение, он заменяет исходный будильник.
Чтобы отменить PendingIntent()
, передайте FLAG_NO_CREATE
в PendingIntent.getService()
, чтобы получить экземпляр намерения (если он существует), затем передайте это намерение в AlarmManager.cancel()
Котлин
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE) if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent) }
Ява
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE); if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent); }
Выберите тип будильника
Одним из первых соображений при использовании повторяющегося будильника является его тип.
Существует два общих типа часов для будильников: «прошедшее реальное время» и «часы реального времени» (RTC). Прошедшее реальное время использует «время с момента загрузки системы» в качестве отсчета, а часы реального времени используют время UTC (настенные часы). Это означает, что прошедшее реальное время подходит для установки будильника на основе течения времени (например, будильник, который срабатывает каждые 30 секунд), поскольку на него не влияет часовой пояс или регион. Тип часов реального времени лучше подходит для будильников, которые зависят от текущего региона.
Оба типа имеют версию «пробуждения», которая говорит о пробуждении ЦП устройства, если экран выключен. Это гарантирует, что будильник сработает в запланированное время. Это полезно, если ваше приложение имеет временную зависимость. Например, если у него есть ограниченное окно для выполнения определенной операции. Если вы не используете версию пробуждения вашего типа будильника, то все повторяющиеся будильники сработают, когда ваше устройство проснется в следующий раз.
Если вам просто нужно, чтобы ваш будильник срабатывал с определенным интервалом (например, каждые полчаса), используйте один из типов реального времени. В целом, это лучший выбор.
Если вам нужно, чтобы ваш будильник срабатывал в определенное время суток, выберите один из типов часов реального времени. Однако обратите внимание, что этот подход может иметь некоторые недостатки. Приложение может некорректно переводиться в другие локали, и если пользователь изменит настройки времени устройства, это может вызвать неожиданное поведение в вашем приложении. Использование типа будильника реального времени также не масштабируется хорошо, как обсуждалось выше. Мы рекомендуем вам использовать будильник «истекшего реального времени», если вы можете.
Вот список типов:
ELAPSED_REALTIME
: запускает ожидающее намерение на основе количества времени с момента загрузки устройства, но не пробуждает его. Прошедшее время включает в себя любое время, в течение которого устройство находилось в спящем режиме.ELAPSED_REALTIME_WAKEUP
: пробуждает устройство и запускает ожидающее намерение по истечении указанного периода времени с момента загрузки устройства.RTC
: запускает ожидающее намерение в указанное время, но не выводит устройство из спящего режима.RTC_WAKEUP
: пробуждает устройство для активации ожидающего намерения в указанное время.
Примеры прошедших сигналов тревоги в реальном времени
Вот несколько примеров использования ELAPSED_REALTIME_WAKEUP
Включите устройство, чтобы будильник сработал через 30 минут, а затем каждые 30 минут:
Котлин
// Hopefully your alarm will have a lower frequency than this! alarmMgr?.setInexactRepeating( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent )
Ява
// Hopefully your alarm will have a lower frequency than this! alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);
Разбудите устройство, чтобы сработать однократный (неповторяющийся) будильник через одну минуту:
Котлин
private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) } alarmMgr?.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent )
Ява
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); alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent);
Примеры будильников реального времени
Вот несколько примеров использования RTC_WAKEUP
.
Включите устройство, чтобы оно сработало примерно в 14:00, и повторяйте это действие один раз в день в одно и то же время:
Котлин
// Set the alarm to start at approximately 2:00 p.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() 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.timeInMillis, AlarmManager.INTERVAL_DAY, alarmIntent )
Ява
// 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 минут:
Котлин
private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) } // Set the alarm to start at 8:30 a.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, 8) set(Calendar.MINUTE, 30) } // setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr?.setRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, 1000 * 60 * 20, alarmIntent )
Ява
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);
Решите, насколько точным должен быть ваш будильник
Как уже было сказано, выбор типа будильника часто является первым шагом в создании будильника. Еще одно отличие заключается в том, насколько точным должен быть ваш будильник. Для большинства приложений setInexactRepeating()
— правильный выбор. При использовании этого метода Android синхронизирует несколько неточно повторяющихся будильников и запускает их одновременно. Это снижает расход заряда батареи.
По возможности избегайте использования точных будильников. Однако для редких приложений, которые имеют жесткие временные требования, вы можете установить точный будильник , вызвав setRepeating()
.
С помощью setInexactRepeating()
вы не можете указать пользовательский интервал так, как это можно сделать с помощью setRepeating()
. Вам придется использовать одну из констант интервала, например INTERVAL_FIFTEEN_MINUTES
, INTERVAL_DAY
и т. д. Полный список см. AlarmManager
.
Отменить будильник
В зависимости от вашего приложения вы можете захотеть включить возможность отмены будильника. Чтобы отменить будильник, вызовите cancel()
в Alarm Manager, передав PendingIntent
, который вы больше не хотите активировать. Например:
Котлин
// If the alarm has been set, cancel it. alarmMgr?.cancel(alarmIntent)
Ява
// If the alarm has been set, cancel it. if (alarmMgr!= null) { alarmMgr.cancel(alarmIntent); }
Включить будильник при перезапуске устройства
По умолчанию все сигналы тревоги отменяются при выключении устройства. Чтобы этого не произошло, вы можете разработать приложение для автоматического перезапуска повторяющегося сигнала тревоги, если пользователь перезагрузит устройство. Это гарантирует, что AlarmManager
продолжит выполнять свою задачу без необходимости вручную перезапускать сигнал тревоги.
Вот шаги:
Установите разрешение
RECEIVE_BOOT_COMPLETED
в манифесте вашего приложения. Это позволяет вашему приложению получатьACTION_BOOT_COMPLETED
, который транслируется после завершения загрузки системы (это работает только в том случае, если приложение уже было запущено пользователем хотя бы один раз):<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Реализуйте
BroadcastReceiver
для приема трансляции:Котлин
class SampleBootReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action == "android.intent.action.BOOT_COMPLETED") { // Set the alarm here. } } }
Ява
public class SampleBootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { // Set the alarm here. } } }
Добавьте приемник в файл манифеста вашего приложения с фильтром намерений, который фильтрует действие
ACTION_BOOT_COMPLETED
:<receiver android:name=".SampleBootReceiver" android:enabled="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> </intent-filter> </receiver>
Обратите внимание, что в манифесте приемник загрузки установлен на
android:enabled="false"
. Это означает, что приемник не будет вызван, если приложение явно не включит его. Это предотвращает ненужный вызов приемника загрузки. Вы можете включить приемник (например, если пользователь устанавливает будильник) следующим образом:Котлин
val receiver = ComponentName(context, SampleBootReceiver::class.java) context.packageManager.setComponentEnabledSetting( receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP )
Ява
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
После включения приемника таким образом он останется включенным, даже если пользователь перезагрузит устройство. Другими словами, программное включение приемника переопределяет настройку манифеста, даже при перезагрузках. Приемник останется включенным, пока ваше приложение не отключит его. Вы можете отключить приемник (например, если пользователь отменит будильник) следующим образом:
Котлин
val receiver = ComponentName(context, SampleBootReceiver::class.java) context.packageManager.setComponentEnabledSetting( receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP )
Ява
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Вызов будильника, пока устройство находится в спящем режиме
Устройства под управлением Android 6.0 (уровень API 23) поддерживают режим Doze , который помогает продлить срок службы батареи устройства. Сигналы тревоги не срабатывают, когда устройство находится в режиме Doze . Все запланированные сигналы тревоги откладываются до тех пор, пока устройство не выйдет из режима Doze. Если вам нужно завершить работу, даже когда устройство находится в режиме ожидания, доступно несколько вариантов:
Установите точный будильник .
Используйте API WorkManager, который создан для выполнения фоновой работы. Вы можете указать, что система должна ускорить вашу работу, чтобы она завершилась как можно скорее. Для получения дополнительной информации см. раздел Планирование задач с помощью WorkManager
Лучшие практики
Каждый выбор, который вы делаете при проектировании повторяющегося будильника, может иметь последствия в том, как ваше приложение использует (или злоупотребляет) системные ресурсы. Например, представьте себе популярное приложение, которое синхронизируется с сервером. Если операция синхронизации основана на времени часов и каждый экземпляр приложения синхронизируется в 23:00, нагрузка на сервер может привести к высокой задержке или даже к «отказу в обслуживании». Следуйте этим рекомендациям по использованию будильников:
Добавьте случайность (джиттер) к любым сетевым запросам, которые срабатывают в результате повторяющегося сигнала тревоги:
Выполняйте любую локальную работу при срабатывании тревоги. «Локальная работа» означает все, что не затрагивает сервер и не требует данных с сервера.
В то же время запланируйте срабатывание будильника, содержащего сетевые запросы, на некоторый случайный период времени.
Сведите частоту срабатывания будильника к минимуму.
Не выводите устройство из спящего режима без необходимости (такое поведение определяется типом будильника, как описано в разделе Выбор типа будильника ).
Не устанавливайте время срабатывания будильника более точно, чем это необходимо.
Используйте
setInexactRepeating()
вместоsetRepeating()
. При использованииsetInexactRepeating()
Android синхронизирует повторяющиеся сигналы тревоги из нескольких приложений и запускает их одновременно. Это уменьшает общее количество раз, когда система должна разбудить устройство, тем самым уменьшая разрядку батареи. Начиная с Android 4.4 (API Level 19), все повторяющиеся сигналы тревоги являются неточными alarm . Обратите внимание, что хотяsetInexactRepeating()
является улучшением по сравнению сsetRepeating()
, он все равно может перегрузить сервер, если каждый экземпляр приложения обращается к серверу примерно в одно и то же время. Поэтому для сетевых запросов добавьте немного случайности к вашим сигналам тревоги, как обсуждалось ранее.По возможности не устанавливайте будильник в зависимости от времени суток.
Повторяющиеся сигналы тревоги, основанные на точном времени срабатывания, плохо масштабируются. Используйте
ELAPSED_REALTIME
, если можете. Различные типы сигналов тревоги более подробно описаны в следующем разделе.