Update issue of an app widget using collection
When you create the PendingIntents
in updateAppWidget
, for each widget, you create these two:
PendingIntent nextButtonPendingIntent = PendingIntent.getBroadcast(context, widgetId, nextButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent prevButtonPendingIntent = PendingIntent.getBroadcast(context, widgetId, prevButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
For both, you set the second argument to widgetId
. The PendingIntent system doesn't look to see if the Intent
argument is different. (In fact, it definititely shouldn't do this - otherwise you couldn't update an existing PendingIntent to a new Intent.) This means that nextButtonPendingIntent
and prevButtonPendingIntent
end up the same.
The solution is to put known, distinct, numbers in that argument and to put other useful information (like the widget Id) inside the intent:
nextButtonIntent.putExtra("widget_id", widgetId);
And to retrieve it in the onReceive():
int widgetId = intent.getIntExtra("widget_id");
WidgetProvider.class
public class WidgetProvider extends AppWidgetProvider
{
private NoteManager m_NoteManagerObject;
private ThemeManager m_ThemeManagerObject;
private SimpleDateFormat m_DateFormater;
private static String WIDGET_NEXT_BUTTON = "in.test.widgetApp.WIDGET_NEXT_BUTTON";
private static String WIDGET_PREV_BUTTON = "in.test.widgetApp.WIDGET_PREV_BUTTON";
public WidgetProvider()
{
// Create an singleton object of NoteManager class
m_NoteManagerObject = NoteManager.getSingletonObject();
// Create an singleton object of ThemeManager class
m_ThemeManagerObject = ThemeManager.getSingletonObject();
// Create an instance of SimpleDateFormat class
m_DateFormater = new SimpleDateFormat("dd-MMM, EEE", Locale.US);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
super.onUpdate(context, appWidgetManager, appWidgetIds);
// Set Date to current Date
m_NoteManagerObject.setWidgetToCurrentDate();
// Get the folder path of all-page-view
ContextWrapper cw = new ContextWrapper(context.getApplicationContext());
File customDirectoryPath = cw.getDir(Utilities.CUSTOM_DIRECTORY_NAME_PREFIX, Context.MODE_PRIVATE);
File allPageDirectoryPath = new File(customDirectoryPath.getPath() + "/" + Utilities.All_PAGE_DIRECTORY_NAME_PREFIX);
if (!(allPageDirectoryPath.exists()))
allPageDirectoryPath.mkdirs();
m_ThemeManagerObject.readTheme(allPageDirectoryPath.getPath());
// Set up the intent that starts the WidgetService, which will
// provide the views for this collection.
// When intents are compared, the extras are ignored, so we need to embed the extras
// into the data so that the extras will not be ignored.
Intent intent = new Intent(context, WidgetService.class);
intent.setData(Uri.fromParts("content", String.valueOf(appWidgetIds), null));
// Instantiate the RemoteViews object for the App Widget layout.
// Set up the RemoteViews object to use a RemoteViews adapter.
// This adapter connects to a RemoteViewsService through the specified intent.
// This is how you populate the data.
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_list);
remoteView.setRemoteAdapter(R.id.widget_list, intent);
// Show day, month and week day inside the widget
remoteView.setTextViewText(R.id.txt_date, m_DateFormater.format(m_NoteManagerObject.getWidgetDate().getTime()));
// The empty view is displayed when the collection has no items.
remoteView.setEmptyView(R.id.widget_list, R.id.widget_empty_text);
// On click of next button
// This section makes it possible for items to have individualized behavior.
// Set the action for the intent.
// When the user touches a particular view, it will have the effect of
// broadcasting ACTION.
Intent nextButtonIntent = new Intent(context, WidgetProvider.class);
nextButtonIntent.setAction(WIDGET_NEXT_BUTTON);
PendingIntent nextButtonPendingIntent = PendingIntent.getBroadcast(context, 0, nextButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setOnClickPendingIntent(R.id.btn_next_month, nextButtonPendingIntent);
remoteView.setInt(R.id.btn_next_month, "setBackgroundResource", m_ThemeManagerObject.getNextButtonBgImage());
// On click of previous button
// This section makes it possible for items to have individualized behavior.
// Set the action for the intent.
// When the user touches a particular view, it will have the effect of
// broadcasting ACTION.
Intent prevButtonIntent = new Intent(context, WidgetProvider.class);
prevButtonIntent.setAction(WIDGET_PREV_BUTTON);
PendingIntent prevButtonPendingIntent = PendingIntent.getBroadcast(context, 0, prevButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setOnClickPendingIntent(R.id.btn_prev_month, prevButtonPendingIntent);
remoteView.setInt(R.id.btn_prev_month, "setBackgroundResource", m_ThemeManagerObject.getPrevButtonBgImage());
// Open application on click of app widget
Intent clickIntent = new Intent(context, AllPageViewActivity.class);
PendingIntent clickPI = PendingIntent.getActivity(context, 0,clickIntent,PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setOnClickPendingIntent(R.id.widget_empty_text, clickPI);
remoteView.setOnClickPendingIntent(R.id.txt_date, clickPI);
appWidgetManager.updateAppWidget(appWidgetIds, remoteView);
}
@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
int numOfDays = 1;
ComponentName thisWidget = new ComponentName(context, WidgetProvider.class);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
if (intent.getAction().equals(WIDGET_NEXT_BUTTON))
{
// Increase no of days by one
m_NoteManagerObject.setWidgetDate(numOfDays);
// Update remote view
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_list);
remoteView.setTextViewText(R.id.txt_date, m_DateFormater.format(m_NoteManagerObject.getWidgetDate().getTime()));
appWidgetManager.updateAppWidget(appWidgetIds, remoteView);
// Update list content of the widget
// This will call onDataSetChanged() method of WidgetDisplay class
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
}
else if (intent.getAction().equals(WIDGET_PREV_BUTTON))
{
// Decrease no of days by one
m_NoteManagerObject.setWidgetDate(-numOfDays);
// Update remote view
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_list);
remoteView.setTextViewText(R.id.txt_date, m_DateFormater.format(m_NoteManagerObject.getWidgetDate().getTime()));
appWidgetManager.updateAppWidget(appWidgetIds, remoteView);
// Update list content of the widget
// This will call onDataSetChanged() method of WidgetDisplay class
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
}
}
}
You can try if changing PendingIntent.FLAG_UPDATE_CURRENT
to PendingIntent.FLAG_CANCEL_CURRENT
in your nextButtonPendingIntent
and prevButtonPendingIntent
pending intents will help.