Android: How do I force the update of all widgets of a particular kind

To force our widgets for a particular widget provider to be updated, we will need to do the following:

  • Set up our provider to receive a specialized broadcast
  • Send the specialized broadcast with:
    1. All the current widget Id’s associated with the provider
    2. The data to send
    3. Keys that only our provider responds to (Important!)
  • Getting our widget to update on click (without a service!)

Step 1 – Set up our AppWidgetProvider

I will not go through the details of creating the info xml file or changes to the Android Manifest – if you don’t know how to create a widget properly, then there are plenty of tutorials out there you should read first.

Here is an example AppWidgetProvider Class:

public class MyWidgetProvider extends AppWidgetProvider {

public static final String WIDGET_IDS_KEY ="mywidgetproviderwidgetids";
public static final String WIDGET_DATA_KEY ="mywidgetproviderwidgetdata";

}

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.hasExtra(WIDGET_IDS_KEY)) {
        int[] ids = intent.getExtras().getIntArray(WIDGET_IDS_KEY);
        if (intent.hasExtra(WIDGET_DATA_KEY)) {
           Object data = intent.getExtras().getParcelable(WIDGET_DATA_KEY);
           this.update(context, AppWidgetManager.getInstance(context), ids, data);
        } else {
            this.onUpdate(context, AppWidgetManager.getInstance(context), ids);
        }
    } else super.onReceive(context, intent);
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
    update(context, appWidgetManager, appWidgetIds, null);
}

//This is where we do the actual updating
public void update(Context context, AppWidgetmanager manager, int[] ids, Object data) {

    //data will contain some predetermined data, but it may be null
   for (int widgetId : ids) {
        .
        .
        //Update Widget here
        .
        .
        manager.updateAppWidget(widgetId, remoteViews);
    }
}

Step 2 – Sending the broadcast

Here we can create a static method that will get our widgets to update. It is important that we use our own keys with the widget update action, if we use AppWidgetmanager.EXTRA_WIDGET_IDS we will not only break our own widget, but others as well.

public static void updateMyWidgets(Context context, Parcelable data) {
    AppWidgetManager man = AppWidgetManager.getInstance(context);
    int[] ids = man.getAppWidgetIds(
            new ComponentName(context,MyWidgetProvider.class));
    Intent updateIntent = new Intent();
    updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    updateIntent.putExtra(MyWidgetProvider.WIDGET_ID_KEY, ids);
    updateIntent.putExtra(MyWidgetProvider.WIDGET_DATA_KEY, data);
    context.sendBroadcast(updateIntent);
}

If using this method with multiple providers MAKE SURE they use different keys. Otherwise you may find widget a’s code updating widget b and that can have some bizarre consequences.

Step 3 – updating on click

Another nice thing to do is to get our widget to update magiacally whenever it is clicked. Add the following code into the update method to acheive this:

RemoteViews views = 
      new RemoteViews(context.getPackageName(),R.layout.mywidget_layout);

Intent updateIntent = new Intent();
updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
updateIntent.putExtra(myWidgetProvider.WIDGET_IDS_KEY, ids);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
      context, 0, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);

views.setOnClickPendingIntent(R.id.view_container, pendingIntent);

This code will cause the onUpdate method to be called whenever the widget is clicked on.

Notes

  • Any call to updateWidgets() will cause all instances of our widget to be updated.
  • Clicking the widget will cause all instances of our widget to be updated
  • NO SERVICE REQUIRED
  • Of course, be careful not to update to often – widget updates use battery power.
  • Bear in mind that the broadcast is received by ALL widget providers, and its our special keys that ensure it is only our widgets that actually update.

Leave a Comment