Alarm setExact () прекращает выполнение - PullRequest
0 голосов
/ 20 ноября 2018

В настоящее время у меня есть проблема с alarmManager на Android.

Когда я запускаю свое приложение, я вызываю метод "startReminderAlarm".Теперь сигнал тревоги активируется в наступающий час и минуту 1. Сигнал тревоги запускает AppReceiver.AppReceiver снова запускает тревогу в течение следующего часа и минуты 1, а затем выполняет некоторый код в методе doInBackground.

С этим шаблоном AppReceiver должен вызываться точно каждый час (минута 1).Но, похоже, работает только в течение нескольких интервалов.Я запустил вчера тревогу и проверил ее сегодня с помощью adb shell dumpsys alarm .Тревога не была упомянута на выходе?

У меня следующая ситуация:

  1. Я не могу воспроизвести эту проблему в эмуляторе
  2. Когда я изменяюБудильник срабатывает каждую минуту, кажется, что он работает.

Мои вопросы:

  1. Есть проблемы с моим кодом?
  2. Есть ли файл журнала, гдея могу видеть исключение, которое может произойти во время фонового выполнения?

Мой код:

// Class AlarmStarter
public static void startReminderAlarm(Context context){
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.HOUR, 1);
    calendar.set(Calendar.MINUTE, 1);
    calendar.set(Calendar.SECOND, 0);
    Log.i(TAG,"Start reminder alarm on " +sdf.format(new Date(calendar.getTimeInMillis())));

    AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent reminderIntent = new Intent(context, AppReceiver.class);
    PendingIntent reminderPendingIntent = PendingIntent.getBroadcast(context, 0, reminderIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    alarmMgr.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), reminderPendingIntent);
}

// Class AppReceiver
public class AppReceiver extends BroadcastReceiver {

    private static final String TAG = "AppReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        AlarmStarter.startReminderAlarm(context);
        new notifyAsyncTask().execute(context);
    }

    private static class notifyAsyncTask extends AsyncTask<Context, Void, Void> {

        private String CHANNEL_ID = "1a2b3c4d";

        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        @Override
        protected Void doInBackground(Context... params) {
            // DO SOME CODE
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Не было никаких проблем с кодом.Проблема заключалась в программном обеспечении управления питанием моего смартфона Huawei.

Как я выяснил, некоторые версии Android от нескольких компаний (Huawei, Samsung, Xiaomi ...) имеют более строгие правила управления питанием.

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

Именно поэтому оно всегда работало в эмуляторе, а не на моем смартфоне.

Решение для моегоСитуация:

  1. Отключение управления питанием для моего приложения
  2. Снова включите сигнализацию

ЕСЛИ КОГДА-то ЕЩЕ ПРОХОДИТ В ЭТОЙ ПРОБЛЕМЕ, ПРОВЕРЬТЕ СВОЕ ПОЛНОМОЧИЕSETTING!

Некоторые полезные команды adb в этом случае:

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

adb shell dumpsys package $packageName |grep stopped

Отображение аварийных сигналов для вашего пакета и некоторая дополнительная информация, например, сколько времени прошло с момента последнего запуска:

adb shell dumpsys alarm |grep -C4 $packageName
0 голосов
/ 20 ноября 2018

Проверьте версию вашего устройства (или эмулятора) для метода setExec().Если версия выше 22, вам следует использовать метод setExactAndAllowWhileIdle().

...