One update for widget
3 June 2012 4 Comments
With the widget of my previous post, if we add more than one widget to our home screen and tap to one of them, all the widgets, all the instances, update themselves.
Also, when we tap “Ok” at the configuration Activity, all the widgets update, again.
This may be the exact behavior we wanted but what if we desire that only one instance, among multiple instances, updates at the click event and after a successful configuration?
The solution that I came up for, is divided in two steps:
-
Whenever we fire an update (
MaLuBuTestWidgetActivity.mainOk()
andMaLuBuTestWidgetProvider.updateAppWidget()
in our case), add the ID of the widget we want to actually get updated to the launched intent. -
Override the default implementation of
onReceive()
ofAppWidgetProvider
(In our case,MaLuBuTestWidgetProvider.onReceive()
) to check for the extra single ID and callonUpdate()
accordingly.
In this example, if we won’t find any single id, we will call the default implementation ofonReceive()
.
Of course, there are many other possible solutions, for example creating a custom Intent with the single ID in it but I think that the principle is the same: memorize which widget we want to update and update only that one. 😀
Now, here are the modifications to our previous example:
MaLuBuTestWidgetActivity.java
[...] public void mainOk(View source) { [...] firstUpdate.setAction("android.appwidget.action.APPWIDGET_UPDATE"); //If you will want to use the default implementation of onReceive() in //the future, then this one is needed. //Otherwise the default onReceive() won't let //android.appwidget.action.APPWIDGET_UPDATE to pass. firstUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); //Put the ID of our widget to identify it later. firstUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetID); context.sendBroadcast(firstUpdate); [...] } [...]
MaLuBuTestWidgetProvider.java
[...] @Override public void onReceive(Context context, Intent intent) { //Check if there is a single widget ID. int widgetID = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); //If there is no single ID, call the super implementation. if(widgetID == AppWidgetManager.INVALID_APPWIDGET_ID) super.onReceive(context, intent); //Otherwise call our onUpdate() passing a one element array, //with the retrieved ID. else this.onUpdate(context, AppWidgetManager.getInstance(context), new int[]{widgetID}); } [...] private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { [...] //Update UI. remoteViews.setTextViewText(R.id.label, getTimeStamp()); //Create the intent. Intent labelIntent = new Intent(context, MaLuBuTestWidgetProvider.class); labelIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); //Put the ID of our widget to identify it later. labelIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); PendingIntent labelPendingIntent = PendingIntent.getBroadcast(context, appWidgetId, labelIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.label, labelPendingIntent); [...] } [...]
That’s all folks: now when we tap a widget only that widget updates and when we hit the “Ok” button of the configuration, only the impending widget updates.
Helpful, thank you:)
You’re welcome! 🙂
Really good tutorial,,,
This is exactly what I was struggling with. Very nice tutorial especially when first developing a widget. Thanks a lot