Как гарантировать срабатывание самописного будильника?

Мда... Не умею я заголовки придумывать(
Суть:
Написал что-то на подобии будильника, и на первый взгляд все было отлично и все работало, но впоследствии обнаружил один баг, а именно не срабатывание этого самого будильника при выключенном экране телефона. Как все сделано: есть сервис в котором запускается таймер который с интервалом в минуту проверяет не настало ли заданное время и не нужно ли ему "сработать" - и это работает, но только до тех пор пока с момента выключения экрана не пройдет приблизительно минуты. По прошествии этой самой минуты будильник перестает срабатывать, и сработает только если разблокировать телефон.
И есть один интересный момент: если подключить телефон к компьютеру и начать читать логи заблокированного телефона при запущенном будильнике - все работает и через пол часа и через час.

инициализация таймера:
nearestTime = changeDB.getNearestSimpleAlarmTime();
        if (mTimer != null) {
            mTimer.cancel();
            mTimer.purge();
            mTimer = null;
        }
        if (nearestTime.getHour() > -1) {
            calendar = Calendar.getInstance();
            int seconds = 60 - calendar.get(Calendar.SECOND);
            System.out.println("первая проверка через " + seconds + " секунд");

            mTimer = new Timer();
            timerTask = new SimpleTimer(nearestTime, getApplicationContext());
            mTimer.schedule(timerTask, seconds * 1000, 60000);
        } else {
            stopSelf();
        }


тело таймера, метод run:
calendar = Calendar.getInstance();
        int minute = calendar.get(Calendar.MINUTE);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);

        if (nearestTime.getHour() < hour || (nearestTime.getHour() == hour && nearestTime.getMinute() < minute) || (nearestTime.getHour() == hour && nearestTime.getMinute() == minute)) {
            Intent scheduledIntent = new Intent(context, AlarmActivity.class);
            scheduledIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            scheduledIntent.putExtra("hour", nearestTime.getHour());
            scheduledIntent.putExtra("minute", nearestTime.getMinute());
            scheduledIntent.putExtra("fulltime", nearestTime.getFulltime());
            context.startActivity(scheduledIntent);
        }
  • Вопрос задан
  • 542 просмотра
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Java
Android developer at Yandex
Это абсолютно неверный подход к будильнику.
Надо делать, используя AlarmManager. В частности, на Android 6+ надо использовать setAndAllowWhileIdle() или setExactAndAllowWhileIdle().
BroadcastReceiver, который будет использоваться с AlarmManager'ом следует наследовать от WakefulBroadcastReceiver'a, чтобы девайс не уснул во время будильника. Звук надо играть в foreground Service (его вы уже освоили).
Также, рекомендую почитать про Doze mode.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
GavriKos
@GavriKos
Попробуйте добавить пермишшн
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Ответ написан
jamakasi666
@jamakasi666 Куратор тега Java
Просто IT'шник.
Нынче многие производители смартфонов на андроиде очень любят переписывать куски андроида. Для примера приведу прошивки emui в которых есть хитрый тасккиллер. Он отправляет проги в глубочайший сон и потихоньку копит все события для программы в очереди, потом программа пробуждается по включению экрана или ее запуску и в программу сыпится вся очередь событий которая накопилась.
Выглядит это ужасно со стороны разработки приложений, но со стороны пользователя круто потому что дико экономит заряд акума. Возможно у вас схожий случай и просто в прошивке похимичили китайцы\индусы?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы