One update for widget

Fork me on GitHub

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:

  1. Whenever we fire an update (MaLuBuTestWidgetActivity.mainOk() and MaLuBuTestWidgetProvider.updateAppWidget() in our case), add the ID of the widget we want to actually get updated to the launched intent.
  2. Override the default implementation of onReceive() of AppWidgetProvider (In our case, MaLuBuTestWidgetProvider.onReceive()) to check for the extra single ID and call onUpdate() accordingly.
    In this example, if we won’t find any single id, we will call the default implementation of onReceive().

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.

Advertisements

About Luong
http://www.linkedin.com/in/manhluong

4 Responses to One update for widget

  1. Helpful, thank you:)

  2. Really good tutorial,,,

  3. This is exactly what I was struggling with. Very nice tutorial especially when first developing a widget. Thanks a lot

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s