Перепланирование тревоги - AlarmManager pendingIntent не является нулевым после принудительного уничтожения - PullRequest
0 голосов
/ 30 января 2020

Я ищу способ понять, когда приложение каким-то образом было принудительно убито, чтобы я мог выполнить некоторые задачи в следующий раз, когда пользователь вручную откроет приложение (перезапустить сигналы тревоги, перепланировать задания, выполнить очистку и т. Д. c ). Чтобы добиться этого, я запланировал AlarmManager далеко в будущем, и каждый раз, когда приложение запускается, я проверяю, существует ли соответствующее ожидающее намерение или нет. Если оно существует, никакого насильственного убийства не произошло, и поэтому я ничего не делаю. Если ожидаемое намерение равно нулю, это означает, что приложение было принудительно убито, а сигнал тревоги отменен, поэтому я планирую его снова и выполняю все необходимые задачи. К сожалению, этот подход не работает: если я принудительно уничтожу приложение из настроек устройства, то при первом открытии приложения ожидающее намерение все еще существует (метод isForceStopped () ниже возвращает false), но если я выхожу из приложения и Я открываю его снова, тогда ожидающее намерение равно нулю (isForceStopped () возвращает true).

Это поведение, которое я нахожу:

  • AlarmManager запланирован при первом запуске приложения

  • Я принудительно убиваю приложение в настройках устройства я запускаю приложение снова -> ожидающее намерение не равно нулю (isForceStopped () возвращает false)

  • Я закрываю приложение и запускаю его снова -> ожидающее намерение null now (isForceStopped () возвращает true, аварийный сигнал перенесен

  • С этого момента аварийный сигнал запланирован, и ожидаемое намерение не является нулевым

Дано В этом случае пользователь должен дважды открыть приложение, прежде чем я смог выполнить необходимые действия после принудительного уничтожения. Мои вопросы:

  • Почему отложенное намерение все еще существует, когда приложение запускается для в первый раз? Я что-то упускаю в своем коде?

  • В общем, есть ли лучшие способы добиться того, что мне нужно (понимаю, что произошло принудительное убийство)?

Текущий код

public class AlarmChecher {

private static final String ACTION_FORCE_STOP = "ACTION_FORCE_STOP";
private Context mContext;
private static final int ALARM_ID = -1;
private static final long TEN_YEARS = TimeUnit.DAYS.toMillis(10 * 365);

public AlarmChecher(Context context) {
    mContext = context;
}

public boolean isForceStopped() {
    PendingIntent pendingIntent = getPendingIntent(mContext, FLAG_NO_CREATE);
    if (pendingIntent == null) {
        setAlarmChecher(mContext);
        return true;
    } else {
        return false;
    }
}

private Intent getIntent(Context context) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName(context, ForceStopRunnable.BroadcastReceiver.class));
    intent.setAction(ACTION_FORCE_STOP);
    return intent;
}

private PendingIntent getPendingIntent(Context context, int flags) {
    Intent intent = getIntent(context);
    return PendingIntent.getBroadcast(context, ALARM_ID, intent, flags);
}

private void setAlarmChecher(Context context) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent pendingIntent = getPendingIntent(context, FLAG_UPDATE_CURRENT);
    long triggerAt = System.currentTimeMillis() + TEN_YEARS;
    if (alarmManager != null) {
        alarmManager.setExact(RTC_WAKEUP, triggerAt, pendingIntent);

    }
}

}

Тогда в методе onCreate () моей деятельности

AlarmChecher alarmChecher = new AlarmChecher(this);
if (alarmChecher.isForceStopped()) {
    //do actions
    alarmJobUtils.rescheduleAll();
} 

1 Ответ

0 голосов
/ 06 февраля 2020

Не используйте отрицательные значения для ALARM_ID. Было много сообщений о странном поведении с отрицательными значениями для requestCode.

...