Вы должны изучить setExactAndAllowWhileIdle Насколько я понимаю, он будет выполняться независимо от того, находится ли телефон в дремоте или нет, и точно в указанное время.
Вы ответили на свой вопрос здесь , но потому что в этом ответе используется WorkManager API, который «предназначен для работы, которая откладывается, то есть не требуется для немедленного запуска - и требуется для надежной работы, даже если приложение завершает работу или перезапускается устройство» ( источник ) Я считаю, что использование AlarmManager - лучший способ справиться с тем, что кажется, что вы пытаетесь сделать.
Однако следует отметить, что для этого все равно потребуется перезапуск сигналов тревоги. -Регистрируется при каждой загрузке, что может показаться сложным, учитывая вопросы и проблемы OP, но я рассмотрел их ниже. Тем не менее, вы должны быть осторожны с тем, что вы делаете, если вы загрузитесь после того, как должен был сработать сигнал тревоги. Например, предположим, что вы создаете приложение-напоминание, в котором вы хотели бы иметь возможность планировать уведомления на go и в таком состоянии, когда ваш телефон выключается непосредственно перед тем, как должно было быть инициировано напоминание, и он включается через 5 минут после этого. должно сработать. Вы все еще активируете уведомление? Вы перенесли это с помощью AlarmManager? Вы просто игнорируете все это вместе? Если вы запускаете его, хотите ли вы, чтобы он запускался до того, как пользователь разблокирует свое устройство, или после того, как он разблокирует устройство, приемлемым?
Вышеупомянутые вопросы - это вещи, которые могут изменить точную реализацию, однако основы то же самое для всех.
- Зарегистрируйте приемник намерений в системе
<application>
<!-- ... -->
<receiver android:name="RECEIVER_NAME">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/> this action is sent before the user unlocks their device-->
</intent-filter>
</receiver>
<!-- ... -->
</application>
- Перерегистрируйте тревоги с помощью AlarmManager в BroadcastReceiver
public class PollReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
if (intent.getAction() != null) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, PollReceiver.class);//this will send the intent back to this class, you can make another broadcast receiver for handling the alarm going off though
i.setAction("ALARM_ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, i, 0);
long triggerTime = System.currentTimeMillis() + 60000; //replace this with when you want your alarm to go off (this will trigger 1 minute from now)
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else if (intent.getAction().equals("ALARM_ACTION")) {
//Show notification or make noise, whatever you are supposed to do when the alarm goes off
}
}
}
}
Решение различных вопросов / проблем в вопросе
ВОПРОС 1: Может ли симулятор не правильно имитировать [перезагружается]?
Однако проблема может быть заключается в том, что вы запускаете проект для запуска эмулятора, а телефон не включается. Вместо того, чтобы нажимать кнопку запуска в Android Studio для запуска эмулятора, вы должны запустить эмулятор самостоятельно с помощью Tools> AVD Manager> Play Button (в столбце действий для соответствующего AVD) или см. Ниже способ перезапуска AVD, пока он работает.
Я бы подумал, что смогу как-то сбрасывать логи в android studio?
Да, можно, внизу Android Studio должна быть вкладка с именем Logcat. На этой вкладке любые подключенные виртуальные или физические устройства будут выводить журналы (вам нужно будет указать, какое устройство вы хотите просмотреть, если подключено несколько). Кроме того, есть возможность использовать командную строку через adb logcat
, или также можно через командную строку запустить перезагрузку через adb reboot
. Вы также можете комбинировать их, чтобы, как только к телефону удалось подключить adb, вы начали прослушивать logcat через adb reboot && adb wait-for-device logcat
. Это работает как для физических устройств, так и для эмулятора, единственная проблема заключается в том, что это выводит журналы для всего, если вы хотите искать указанный c текст, вы можете использовать adb reboot && adb wait-for-device logcat | grep "string-to-search-for"
(Windows может заменить «grep» with "findstr")
СТРАННЫЙ СЦЕНАРИЙ 1: Если у меня есть ДВА android студийных проекта, откройте мое личное приложение, а затем откройте приложение-образец ссылки ПОСЛЕ моего проекта, я вижу тост "Alarms Запланированное". Однако я не могу найти журналов на PollReceiver, пока этот сигнал не сработает через 5 секунд. Я ожидал увидеть журнал от PollReceiver при запуске, но не увидел его раньше 5 секунд. Другой запуск этого позже не дал никаких журналов (кроме всплывающего всплывающего сообщения, поэтому я знаю, что он запускал этот код ... очень странно). Затем я добавил сообщение журнала в ScheduledServiceDemoActivity, и теперь я не могу воспроизвести 0 таких журналов за один раз.
Поведение, которое вы описываете в первой части, является правильным и должно произойти независимо от того, сколько Android Открытые у вас проекты Studio и какое приложение запускается первым. Приложение подает повторяющийся сигнал, который выключается go через 5 секунд, а затем каждые 15 минут. Если вы добавили журнал к методу onReceive
, вы не увидите его до тех пор, пока этот метод не будет вызван, а это произойдет до тех пор, пока не сработает сигнал тревоги. Что касается второй части, где вы не получали никаких журналов, возможно, вы не позволили приложению работать в течение 5 секунд, поэтому журналы не будут напечатаны. Следует отметить, что когда вы запускаете приложение через Android Studio, это не совсем то же самое, как если бы вы запускали его с телефона, нажав на значок. Это также объясняет, почему вы не смогли воссоздать его после добавления журнала в действие.
СТРАННЫЙ СЦЕНАРИЙ 2: Я ПЕРЕЗАГРУЖАЮ телефон (или он продолжает запускать мое приложение, и сценарий 1 продолжает работать). Затем я загружаю ТОЛЬКО пример приложения ссылки, ничего не происходит. Я жду 90 секунд и ничего.
Пример приложения должен запускать журнал примерно каждые 15 минут, а не 90 секунд (900 000 мс, а не 90 000 мс). Однако образец приложения должен запускать журнал через 5 секунд (не совсем 5 секунд, хотя из-за способа Android работает) после запуска приложения или после перезагрузки.
Я никогда не могу получить PollReceiver срабатывать при запуске. ScheduledServiceDemoActivity, кажется, является настоящей точкой входа, и я никогда не добавлял службу в свой приведенный выше код, поскольку я не хотел ее ... просто хотел, чтобы меня уведомили о загрузке, чтобы перенести аварийные сигналы. Это приводит меня к возможному выводу, что ScheduledServiceDemoActivity должен запускаться на определенных устройствах при загрузке, а PollReceiver - для других устройств при загрузке? Если да, то какие имитаторы могут имитировать этот другой сценарий загрузки?
Вам действительно следует ознакомиться с жизненным циклом приложения и жизненным циклом активности . ScheduledServiceDemoActivity - это то, что открывается при запуске приложения через Android Studio или при нажатии его значка на панели запуска, но BroadcastReceiver также является еще одной точкой входа для приложения. В этом случае он запускается, когда Android отправляет намерение с действием ACTION_BOOT_COMPLETED. ScheduledServiceDemoActivity никогда не запустится при загрузке. Входящий в комплект AVD может правильно моделировать сценарий загрузки и запускать PollReceiver.
EDIT (у меня была другая мысль) На моем телефоне samsung я проверил разрешения, и их всего ТРИ, хотя я добавил их 4 строки в моем манифесте
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- so we can send a text -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- So we can reschedule alarms that went off while powered off -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- read contacts so they can easily choose their friends -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
Загрузочной загрузки там нет. это проблема? ИЛИ телефоны не отображают завершенную загрузку для пользователей, поскольку это может сбивать с толку?
Большинство вариантов Android (если не все), поставляемые на устройства, не будут отображать разрешения, которые считаются "нормальный" от Google. По сути, будут отображаться только разрешения, которые не предоставляются автоматически во время установки и считаются "опасными" , поскольку они могут повлиять на сохраненные данные пользователя или поведение других приложений.