2014-10-25 2 views
0

У меня есть виджет, показывающий 10 изображений. При нажатии на одно из этих изображений открывается действие, показывающее некоторую информацию, соответствующую этому изображению. Данные хранятся в базе данных sqlite.Ожидаемые незарегистрированные виджеты

Каждую неделю эти изображения меняются (его пул> 100 различных объектов, каждую неделю отображается другое подмножество из них).

метод My OnUpdate выглядит следующим образом:

List<Champion> champions = // a list of 10 champions out of 100 fetched from db 
int[] imageIds = // drawable ids for the 10 champions 

// creating the pending intents 
PendingIntent[] pIntents = new PendingIntent[champions.size()]; 
for(int i = 0; i < champions.size(); i++) 
{ 
    Intent intent = new Intent(context, ChampionActivity.class); 
    intent.putExtra(ChampionActivity.KEY_ID, champions.get(i).getChampionId()); 
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    pIntents[i] = PendingIntent.getActivity(context, i, intent, 0); 
} 

// updating widgets with the new images and intents 
for(int widgetId : appWidgetIds) 
{ 
    RemoteViews view = new RemoteViews(
          context.getPackageName(), 
          R.layout.widget 
         ); 
    for(int i = 0; i < imageViewIds.length; i++) 
    { 
     view.setImageViewResource(imageViewIds[i], imageIds[i]); 
     view.setOnClickPendingIntent(imageViewIds[i], pIntents[i]); 
    } 
    appWidgetManager.updateAppWidget(widgetId, view); 
} 

Этот виджет установлен, чтобы обновить себя каждые 30 минут. Обновление изображений отлично работает, но как-то ожидающие намерения, похоже, не обновляются.

Пример:
- Пользователь добавляет виджет к своему рабочему экрану, когда показан чемпион A.
- Через 30 минут, чемпион заменяются чемпион B, изображение обновляется соответственно
- Щелчок на чемпион B по-прежнему ведет пользователь к Чемпиону (умысел экстра идентификатор, а не идентификатор О.Б. B)

Что я делаю неправильно?
Заранее спасибо

ответ

3

Чтобы обновить дополнительные данные в PendingIntent, если он уже существует, вы можете использовать флаг PendingIntent.FLAG_UPDATE_CURRENT. Поскольку вам нужно только одно ожидающее намерение активно за раз, это более уместно. Не забудьте передать тот же код запроса. Код запроса может быть appWidgetId, чтобы сделать его уникальным в случае нескольких экземпляров. [Благодаря @shoerat для определения проблемы].Из docs:

Флаг, указывающий, что если описанная PendingIntent уже существует, затем сохранить его, но заменить его дополнительные данные с тем, что в этом новом Intent. Для использования с getActivity (Context, int, Intent, int), getBroadcast (Context, int, Intent, int) и getService (Context, int, Intent, int).

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

Вот код:

Intent intent = new Intent(context, ChampionActivity.class); 
intent.putExtra("widgetId", appWidgetId); 
pIntents[i] = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
+0

+1: это кажется более подходящим способом обработки этой проблемы. Тем не менее, мне интересно, вызывает ли использование фиксированного кода запроса несогласованность при наличии нескольких виджетов? – ozbek

+0

@shoerat Спасибо, что подняли вопрос, Вы правы. В случае нескольких экземпляров можно использовать 'appWidgetId'. Я обновил свой ответ. –

4

Это обычная ошибка, то есть, ваша проблема в этой строке:

pIntents[i] = PendingIntent.getActivity(context, i, intent, 0); 

В частности, проблема с requestCode: она постоянна в течение всего срока службы виджета. Поэтому платформа не распознает новый Intent как «новый» и будет доставлять тот же (то есть первый) PendingIntent все время. Вам нужно использовать новый код запроса, если вы хотите получить новый Intent. Из docs:

... это важно знать, когда два Intents считаются одинаковыми для целей извлечения PendingIntent. Обычная ошибка, которую делают люди, заключается в создании нескольких объектов PendingIntent с Intents, которые изменяются только в их «лишнем» содержимом, ожидая, что каждый раз будет получать другой PendingIntent. Этого не происходит. Части намерения, которые используются для сопоставления, являются теми же, что определены Intent.filterEquals. Если вы используете два объекта Intent, которые эквивалентны Intent.filterEquals, вы получите тот же PendingIntent для обоих из них.

Какой тип возвращаемого значения для champions.get(i).getChampionId()? Это похоже на хорошего кандидата для использования в качестве кода запроса, если это int. Таким образом, использование

pIntents[i] = PendingIntent.getActivity(context, champions.get(i).getChampionId(), intent, 0); 

, вероятно, устранит проблему.

Надеюсь, это поможет.

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