2012-09-24 3 views
5

Я пишу приложение для 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 в части данных намерения, но это также не помогло.

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

ответ

2

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

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); 
+0

Благодарим за помощь, это решило проблему, но создало новую. Дополнительные объекты предупреждений передаются службе, но в качестве дополнительных служб, управляемых AlarmManager, уже запущенные AlarmManagers продолжают работать. Поэтому количество диспетчеров AlarmManager увеличивается каждый раз, когда я добавляю объект предупреждения. Это означает, что у меня есть один запуск для одного объекта оповещения, один на двоих, один на три и т. Д. Я думаю, было бы лучше, если бы существовал только тот, у кого было текущее количество существующих предупреждений, поэтому мне все равно нужно остановить старый AlarmManager. Службы останавливаются вызовом stopSelf(). – user1695117

+0

ОК. Я не был уверен, что вы хотели сделать. На основе этого комментария звучит так, будто вы хотите отменить существующий сигнал тревоги и создать новый с новыми параметрами. Я отредактирую свой ответ для этого. –

+0

Это сработало отлично. Кажется, все, что я отсутствовал, было правильным флагом. Спасибо за помощь. – user1695117

Смежные вопросы