Как обновить отправку данных службе, используя намерение, когда служба запускается диспетчером аварийных сигналов?

Я пишу приложение для Android, в котором пользователь может выбрать несколько акций для просмотра и получать предупреждения, если будет задано предопределенное условие предупреждения. Данные запаса сохраняются в 5 объектах пользовательского Parcelable класса «alert» (один объект на акцию и условие). Периодическое обновление данных выполняется через службу, запущенную AlarmManager. Объекты оповещения передаются службе, помещая их в Intent, который помещается в PendingIntent AlarmManager.

Intent intent = new Intent(this, UpdateService.class); Bundle b = new Bundle(); saveAlertsToBundle(b); intent.putExtras(b); intent.setData(Uri.parse("updateManager")); PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); // 1min intervall long intervall = DateUtils.MINUTE_IN_MILLIS * 1; // time of first start long firstStartDelay = DateUtils.SECOND_IN_MILLIS * 30; long firstStart = System.currentTimeMillis() + firstStartDelay; AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); // kill running am.cancel(pendIntent); //start new am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent); 

Моя проблема:

При первом запуске службы, когда только один объект оповещения передается службе, все работает нормально. Как только существует больше объектов оповещения, они также должны быть переданы службе, но это не работает с приведенным выше кодом. Служба не получает обновленные намерения с дополнительными объектами оповещения, но только исходные, содержащие только один объект оповещения. Приведенный выше код правильно создает намерение, содержащее дополнительный объект оповещения, но никогда не доходит до службы.

Поэтому мой вопрос заключается в том, как передать обновленное намерение уже запущенному AlarmManager.

Я уже пробовал остановить AlarmManager (строка в // kill running comment) и перезапустить его, но это не работает. Возможно, из-за намерения не содержать те же объекты предупреждения, что и в момент его создания? Я попытался исправить это, установив uri в части данных намерения, но это также не помогло.

Спасибо за помощь.

Ваша проблема заключается в том, как работает PendingIntent . Система управляет пулом PengingIntent s. Когда ваш код делает:

 PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); 

Это заставляет систему искать PendingIntent который соответствует параметрам, которые вы передали (в данном случае, вашему Intent . Однако алгоритм сопоставления, используемый PendingIntent сравнивает только определенные поля Intent чтобы определить, является ли это тем, В частности, он не сравнивает дополнительные функции, поэтому это означает, что после создания первого PendingIntent вызов PendingIntent.getService() всегда возвращает тот же PendingIntent из пула (а не создает новый, Это то, что вы хотите).

Чтобы сделать вызов PendingIntent.getService() создайте новый PendingIntent каждый раз, когда вы его вызываете, попробуйте сделать параметры, которые вы передаете уникальному вызову, например:

 int requestCode = (int) System.currentTimeMillis(); // Create unique request code PendingIntent pendIntent = PendingIntent.getService(this, requestCode, intent, 0); 

Поскольку requestCode будет отличаться для каждого вызова PendingIntent.getService() , это должно решить вашу проблему.

EDIT Основываясь на комментариях OP ниже

Вы хотите отменить существующий аварийный сигнал и создать новый с новыми данными. В этом случае вам не нужно использовать уникальные идентификаторы, потому что вы хотите иметь только один PendingIntent в пуле. Но вы хотите изменить данные для этого. Попробуй это:

 // Create a PendingIntent (or update the existing PendingIntent with new values PendingIntent pendIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); // cancel any pending alarms am.cancel(pendIntent); //start new am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent);