Surprise: why don't you just override the onReceive () method of WidgetProvider? Since the AppWidgetProvider application is extended from BroadcastReceiver, it is completely legal if you call super.onReceive ().
The intent that you get through onReceive () contains widget identifiers as optional if it was called by AppWidgetHost (Launcher). If you call it yourself, you need to add the necessary additional services yourself.
It looks like an elegant way to launch WidgetProvider from any other action, while preserving the original functionality.
Remember: AppWidgetProvider is a handy class that makes widget development easier, but basically it's just BroadcastReceiver.
I solved it like this:
public class WidgetProvider extends AppWidgetProvider { public static final String ACTION_RESTART_SERVICE = "ACTION_RESTART_SERVICE"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onEnabled() called."); if (intent.getAction() != null && intent.getAction().equals(WidgetProvider.ACTION_RESTART_SERVICE)) {
And in your activity / fragment:
/** * Restart the update service via WidgetProvider to reflect new profile and settings * @param context Context is required */ private void restartService(Context context) { Intent intent = new Intent(context, WidgetProvider.class); intent.setAction(WidgetProvider.ACTION_RESTART_SERVICE); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { // Send intents to all widget provider classes intent.setClass(context, WidgetProviderSize1.class); getActivity().sendBroadcast(intent); intent.setClass(context, WidgetProviderSize2.class); getActivity().sendBroadcast(intent); intent.setClass(context, WidgetProviderSize3.class); getActivity().sendBroadcast(intent); intent.setClass(context, WidgetProviderSize4.class); getActivity().sendBroadcast(intent); intent.setClass(context, WidgetProviderSize5.class); getActivity().sendBroadcast(intent); } else getActivity().sendBroadcast(intent); }
It looks a bit complicated because I have a dynamic resizable widget with JellyBean and a fixed widget size below this OS version, but the solution should be clear.
Even simpler would be to simply send the android .appwidget.action.APPWIDGET_UPDATE broadcast, just like Launcher, to directly call onUpdate () of your WidgetProvider.
Then there is a completely different option available: let the Updateservice independently obtain the WidgetIDs, so there is no need to extract them from the update intent. This is normal if all widgets basically use the same configuration and need to be updated if something changes in the configuration:
private int[] getAppWidgetIDs(AppWidgetManager appWidgetManager) { int[] widgetIdsOfOneProviderSize1 = getAppIdsOfSingleProvider(appWidgetManager, WidgetProviderSize1.class); int[] widgetIdsOfOneProviderSize2 = getAppIdsOfSingleProvider(appWidgetManager, WidgetProviderSize2.class); int[] widgetIdsOfOneProviderSize3 = getAppIdsOfSingleProvider(appWidgetManager, WidgetProviderSize3.class); int[] widgetIdsOfOneProviderSize4 = getAppIdsOfSingleProvider(appWidgetManager, WidgetProviderSize4.class); int[] widgetIdsOfOneProviderSize5 = getAppIdsOfSingleProvider(appWidgetManager, WidgetProviderSize5.class); int[] widgetIdsOfOneProvider = getAppIdsOfSingleProvider(appWidgetManager, WidgetProvider.class); int allWidgetIds[] = new int[widgetIdsOfOneProviderSize1.length + widgetIdsOfOneProviderSize2.length + widgetIdsOfOneProviderSize3.length + widgetIdsOfOneProviderSize4.length + widgetIdsOfOneProviderSize5.length + widgetIdsOfOneProvider.length]; int index = 0; for (int id : widgetIdsOfOneProviderSize1) { allWidgetIds[index] = id; index ++; } for (int id : widgetIdsOfOneProviderSize2) { allWidgetIds[index] = id; index ++; } for (int id : widgetIdsOfOneProviderSize3) { allWidgetIds[index] = id; index ++; } for (int id : widgetIdsOfOneProviderSize4) { allWidgetIds[index] = id; index ++; } for (int id : widgetIdsOfOneProviderSize5) { allWidgetIds[index] = id; index ++; } for (int id : widgetIdsOfOneProvider) { allWidgetIds[index] = id; index ++; } return allWidgetIds; } private int[] getAppIdsOfSingleProvider(AppWidgetManager appWidgetManager, Class cls) { ComponentName thisWidget = new ComponentName(getApplicationContext(), cls); int[] widgetIdsOfOneProvider = appWidgetManager.getAppWidgetIds(thisWidget); return widgetIdsOfOneProvider; }
Yes, I had to use ArrayUtils to combine arrays ... leaves room for improvement; -)