Android PendingIntent FLAG_NO_CREATE не возвращает значение null

У меня проблемы с PendingIntents. Каждый раз, когда мое приложение открывается, оно будет планировать некоторые трансляции. Моя проблема в том, что уже существующие PendingIntents не распознаются.

Я знаю, что PendingIntents и unterlaying Intent должны быть созданы с одинаковыми параметрами.

Это мой код... запущенный в моем Launcher Activity как Asynctask.

        long nextExecute = getNextExecute(t);

        if (nextExecute > System.currentTimeMillis()) {

            int tt = 12;

            intent = new Intent(context, BirthExecutor.class);
            intent.putExtra(Target.ROW_ID, tt);

            PendingIntent pending = PendingIntent.getBroadcast(context, 10, intent, PendingIntent.FLAG_NO_CREATE);

            if (pending != null) {

                manager.set(AlarmManager.RTC_WAKEUP, nextExecute, pending);

                BirthLog log = new BirthLog("Scheduled " + t.getFirstname() + " " + t.getLastname() + " on " + df.format(nextExecute));
                log_helper.insertLog(log);

            } else {

                BirthLog log = new BirthLog(t.getFirstname() + " " + t.getLastname() + " already active!");
                log_helper.insertLog(log);

            }

            intent = new Intent(LogAdapter.LOG_RECEIVE_ACTION);
            context.sendBroadcast(intent);

        }

Каждый раз выполняется один и тот же код, но почему ожидающая переменная не равна нулю? Должно быть !!! Я жестко закодировал requestId, также жестко запрограммирован putExtra.

ИЗМЕНИТЬ

У меня есть еще одна функция для обновления этого расписания. Только если я выполню эту функцию, PendingIntents больше не распознаются. Я пытался использовать тот же объект контекста в качестве статической ссылки, но это тоже не удалось.

public void updateTask(Target t) {

    if (t.getTime() == null || t.getRow() == null)
        return;

    Intent intent;
    SimpleDateFormat df = new SimpleDateFormat("HH:mm dd.MM.yyyy", Locale.US);

    long nextExecute = getNextExecute(t);

    if (nextExecute > System.currentTimeMillis()) {

        intent = new Intent(static_context, BirthExecutor.class);
        intent.putExtra(Target.ROW_ID, 12);

        PendingIntent pending = PendingIntent.getBroadcast(static_context, 10, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        if (pending != null) {

            manager.set(AlarmManager.RTC_WAKEUP, nextExecute, pending);

            BirthLog log = new BirthLog("Scheduled " + t.getFirstname() + " " + t.getLastname() + " on " + df.format(nextExecute));
            log_helper.insertLog(log);
            Log.d("birth", log.getComment());

        } else {

            BirthLog log = new BirthLog(t.getFirstname() + " " + t.getLastname() + " ERROR. TIME: " + df.format(nextExecute));
            log_helper.insertLog(log);
            Log.d("birth", log.getComment());

        }

        intent = new Intent(LogAdapter.LOG_RECEIVE_ACTION);
        static_context.sendBroadcast(intent);

    }

}

ИЗМЕНИТЬ 2

Хорошо, это имеет смысл, если он возвращает ненулевой результат, если это ожидающее намерение уже запланировано. Я изменил свой код. Каждый раз, когда я переворачиваю свой телефон, запускается основное действие onCreate и выполняется асинхронная задача планирования. НО результат всегда нулевой?!?! Это должен быть ненулевой результат, если уже есть запланированное отложенное намерение, верно?

@Override
protected Void doInBackground(Void... params) {

    Intent intent;
    SimpleDateFormat df = new SimpleDateFormat("HH:mm dd.MM.yyyy", Locale.US);

    for (Target t : target_helper.getAllTarget()) {

        long nextExecute = getNextExecute(t);

        if (nextExecute > System.currentTimeMillis()) {

            PendingIntent pending = getPendingIntent(context, t, false);

            if (pending != null) {

                BirthLog log = new BirthLog(t.getFirstname() + " " + t.getLastname() + " already active!");
                log_helper.insertLog(log);

            } else {

                manager.set(AlarmManager.RTC_WAKEUP, nextExecute, pending);

                BirthLog log = new BirthLog("Scheduled " + t.getFirstname() + " " + t.getLastname() + " on " + df.format(nextExecute));
                log_helper.insertLog(log);

            }

            intent = new Intent(LogAdapter.LOG_RECEIVE_ACTION);
            context.sendBroadcast(intent);

        }

    }

    return null;

}

private PendingIntent getPendingIntent(Context context, Target t, boolean update) {

    Intent intent = new Intent(context, BirthExecutor.class);
    intent.putExtra(Target.ROW_ID, t.getRow());

    if (update) {
        return PendingIntent.getBroadcast(context, t.getRow().intValue(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
    } else {
        return PendingIntent.getBroadcast(context, t.getRow().intValue(), intent, PendingIntent.FLAG_NO_CREATE);
    }

}



Ответы (2)


Документация неверна. Если вы используете PendingIntent.FLAG_NO_CREATE при вызове PendingIntent.getBroadcast(), он вернет null если не будет найдено подходящее PendingIntent. В противном случае он вернет соответствующий PendingIntent.

В документации написано наоборот, но это не так :-(

person David Wasser    schedule 09.03.2014
comment
омг, если это действительно так, гррр... посмотрю... спасибо ;) - person Pascal; 14.03.2014
comment
На самом деле, если подумать об этом дольше нескольких секунд, становится ясно, что нет смысла возвращать null, если есть совпадающее PendingIntent, и ненулевое значение, если его нет, так как, устанавливая FLAG_NO_CREATE, вы указали что вы не хотите, чтобы Android создавал новый PendingIntent. Что он должен вернуть как ненулевой результат? - person David Wasser; 14.03.2014
comment
ты решил это? я столкнулся с точно такой же проблемой - person Yamen Nassif; 17.01.2015

Система делает именно то, что написано в документации:

интервал FLAG_NO_CREATE

Флаг, указывающий, что если описанный PendingIntent еще не существует, то просто вернуть null вместо его создания.

С учетом сказанного, если я не хочу запускать свою задачу, если она уже запущена, я делаю следующее:

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent == null) {
    pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    // start it only it wasn't running already
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10 * 60 * 1000, pendingIntent);
}
person Andrei    schedule 22.01.2017