Возможно ли создать несколько PendingIntents с тем же кодом requestCode и разными дополнительными функциями?

Я использую AlarmManager для планирования где-то между 1 и 35 аварийными сигналами (в зависимости от ввода пользователем). Когда пользователь запрашивает расписание новых аварийных сигналов, мне нужно отменить текущие аварийные сигналы, поэтому я создаю все свои аварийные сигналы с одним и тем же кодом запроса, определенным в final переменной.

 // clear remaining alarms Intent intentstop = new Intent(this, NDService.class); PendingIntent senderstop = PendingIntent.getService(this, NODIR_REQUESTCODE, intentstop, 0); am.cancel(senderstop); // loop through days if (sched_slider.getBooleanValue()) for (int day = 1; day < 8; day++) { if (day == 1 && sun.isChecked()) scheduleDay(day); if (day == 2 && mon.isChecked()) scheduleDay(day); if (day == 3 && tue.isChecked()) scheduleDay(day); if (day == 4 && wed.isChecked()) scheduleDay(day); if (day == 5 && thu.isChecked()) scheduleDay(day); if (day == 6 && fri.isChecked()) scheduleDay(day); if (day == 7 && sat.isChecked()) scheduleDay(day); } ... public void scheduleDay(int dayofweek) { Intent toolintent = new Intent(this, NDService.class); toolintent.putExtra("TOOL", "this value changes occasionally"); PendingIntent pi = PendingIntent.getService(this, NODIR_REQUESTCODE, toolintent, 0); calendar.set(Calendar.DAY_OF_WEEK, dayofweek); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, 0); am.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, pi); } 

Здесь, если у пользователя есть sun (это CheckBox), он будет планировать будильник для запуска каждое воскресенье в hour и minute . Вы можете видеть, что каждый созданный таким образом аварийный сигнал имеет тот же код requestCode, но дополнительный TOOL иногда изменяется для каждого аварийного сигнала.

Тем не менее, в моем тестировании, когда будильник отключается и моя служба работает, дополнительные функции от намерения теперь равны null . Этот вопрос предполагает, что использование PendingIntent.FLAG_CANCEL_CURRENT разрешит это, но не отменяет ли это других PendingIntents?

Вкратце:

Может ли кто-нибудь объяснить, как работает PendingIntents, со ссылкой на создание нескольких из них с тем же кодом запроса и различными дополнительными функциями? Какие флаги (если есть) я должен использовать?

    На самом деле, вы не создаете PendingIntent s. Вы запрашиваете их из фреймворка Android. Когда вы запрашиваете PendingIntent из фреймворка Android, он проверяет, есть ли уже PendingIntent который соответствует критериям, которые вы передаете в качестве аргументов. Если это так, он не создает новый PendingIntent , он просто возвращает вам «токен», указывающий на существующий PendingIntent . Если он не найдет подходящий PendingIntent , он создаст один, а затем вернет вам «токен», который указывает на тот, который он только что создал. Есть несколько флагов, которые вы можете изменить, чтобы изменить это поведение, но не так много. Самое главное, чтобы понять здесь, – это то, как платформа Android выполняет сопоставление.

    Для этого он проверяет соответствие следующих параметров (сравнение существующего PendingIntent с параметрами, которые вы прошли):

    • Коды запросов должны быть одинаковыми. В противном случае они не совпадают.
    • «Действие» в Intent должно быть одинаковым (или оба нуля). В противном случае они не совпадают.
    • «Данные» в Intent должны быть одинаковыми (или оба нуля). В противном случае они не совпадают.
    • «Тип» (данных) в Intent должен быть одинаковым (или оба нуля). В противном случае они не совпадают.
    • «Пакет» и / или «компонент» в Intent должны быть одинаковыми (или оба нулевыми). В противном случае они не совпадают. Поля «package» и «component» установлены для «явного» Intent s.
    • Список «категорий» в Intent должен быть одинаковым. В противном случае они не совпадают.

    Вы должны заметить, что «дополнительные функции» не указаны в списке выше . Это означает, что если вы запрашиваете PendingIntent «дополнительные» не учитываются, когда платформа Android пытается найти соответствующий PendingIntent . Это распространенная ошибка, которую делают разработчики.

    Теперь мы можем обратиться к дополнительным флагам, которые вы можете добавить, чтобы изменить поведение запроса PendingIntent :

    FLAG_CANCEL_CURRENT – Если вы укажете этот флаг, если найден соответствующий PendingIntent , то PendingIntent будет отменен (удален, удален, недействителен) и будет создан новый. Это означает, что любые приложения, содержащие «токен», указывающие на старый PendingIntent , не смогут использовать его, потому что он больше недействителен.

    FLAG_NO_CREATE Когда вы укажете этот флаг, если найден соответствующий PendingIntent «токен», указывающий на существующий PendingIntent (это обычное поведение). Однако, если не найдено подходящего PendingIntent , новый не создается и вызов просто возвращает значение null . Это можно использовать, чтобы определить, существует ли активный PendingIntent для определенного набора параметров.

    FLAG_ONE_SHOT – Когда вы укажете этот флаг, PendingIntent может использоваться только один раз. Это означает, что если вы дадите «токен» для этого PendingIntent для нескольких приложений, после первого использования PendingIntent он будет отменен (удален, удален, недействителен), чтобы всякая попытка его использовать в будущем не удалась.

    FLAG_UPDATE_CURRENT Когда вы укажете этот флаг, если найден соответствующий PendingIntent , «дополнительные» в этом PendingIntent будут заменены «дополнительными» в Intent которые вы передаете в качестве параметра getxxx() . Если соответствующий PendingIntent не найден, создается новый (это обычное поведение). Это можно использовать для изменения «дополнительных» в существующем PendingIntent где вы уже дали «токен» другим приложениям и не хотите аннулировать существующий PendingIntent .

    Позвольте мне попытаться решить вашу конкретную проблему:

    Вы не можете иметь более одного активного PendingIntent в системе, если код запроса, действие, данные, тип и параметры пакета / компонента одинаковы. Таким образом, ваше требование иметь до 35 активных PendingIntent с PendingIntent и тем же кодом запроса, действиями, данными, типом и параметрами пакета / компонента, но с разными «дополнительными функциями», невозможно.

    Я бы предположил, что вы либо используете 35 разных кодов запросов, либо создаете 35 разных уникальных параметров действия для вашего Intent .

    Да, возможно, только одно уникальное действие для каждого сигнала тревоги

    intent.setAction ( “uniqueCode”);

     Intent intent = new Intent(context, MyAlarmReciver.class); intent.setAction("uniqueCode"); PendingIntent pendingIntent = PendingIntent.getBroadcast(activity, 0, intent, 0); AlarmManager alarmManager = (AlarmManager) context.getSystemService(activity.ALARM_SERVICE); Calendar c = Calendar.getInstance(); c.add(Calendar.MINUTE, 1); alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent); 
    Interesting Posts
    Давайте будем гением компьютера.