AppWidgetProvider: onAppWidgetOptionsChanged not being called on widget placement

3k views Asked by At

According to the documentation on onAppWidgetOptionsChanged in AppWidgetProvider: "This is called when the widget is first placed and any time the widget is resized."

However, when I place my widget on the stock launcher in Android 4.2 and 4.3, this method is not being called immediately (only after I resize the widget). I tried it on my own app, as well as CommonsWare's https://github.com/commonsguy/cw-omnibus/tree/master/AppWidget/Resize

Is there something I am missing?

EDIT: The only launcher I have found that makes this method work correctly as described by the Google documentation is Action Launcher Pro; nice job and thanks, Chris Lacy! Why does the stock launcher not work? Anyone else have this issue?

2

There are 2 answers

2
labtopia On BEST ANSWER

thanks for calling attention to this issue. I will be updating the Android documentation to reflect this.

However, instead of forcing a call to onAppWidgetOptionsChanged() in onUpdate(), we would recommend an approach such as the following:

public class AppWidget extends AppWidgetProvider {

    .... 

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

super.onUpdate(context, appWidgetManager, appWidgetIds);

final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];
            Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
            updateWidget(context, appWidgetManager, appWidgetId, options);
        }

}


public void onAppWidgetOptionsChanged (Context context, AppWidgetManager 
        appWidgetManager, int appWidgetId, Bundle newOptions) {

    updateWidget(context, appWidgetManager, appWidgetId, newOptions);
}

private void updateWidget(Context context, AppWidgetManager appWidgetManager,

        int appWidgetId, Bundle options) {

    // Do whatever you need to do to the widget. Include any customization based
    // on the size, included in the options. Be sure to have a graceful fallback if
    // no valid size data is included in the bundle.


    }

    ...
}
2
Eric Cochran On

So, the documentation says about onUpdate(): "...[I]f you have declared a configuration Activity, this method is not called when the user adds the App Widget, but is called for the subsequent updates." Well, apparently that is not true, either. onUpdate() is called, even though I have a configuration Activity for my widget.

Anyway, calling onAppWidgetOptionsChanged() from onUpdate() seems to be a workaround in 4.2+-based launchers because onUpdate() is called when the widget is first placed on the home screen, and we can get the Bundle appWidgetOptions from the AppWidgetManager instance.

@Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetIds[]){
      super.onUpdate(context, appWidgetManager, appWidgetIds);
      final int N = appWidgetIds.length;
      for (int i=0; i<N; i++) {
          int appWidgetId = appWidgetIds[i];
          Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
          if(options!=null){
              int nwidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
              int nheight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
              onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, options);
          }
      }
  }