想知道:为什么不直接覆盖WidgetProvider的onReceive()方法呢?由于AppWidgetProvider是从BroadcastReceiver扩展而来的,只要调用super.onReceive(),这是完全合法的。
通过onReceive()获取的Intent包含Widget Ids作为Extra,如果它是由AppWidgetHost(Launcher)调用的。如果您自己调用它,则必须自己添加所需的extras。
这看起来是一种优雅的方式,可以从任何其他活动触发WidgetProvider,同时保持其原始功能。
请记住:AppWidgetProvider是一个方便的类,易于开发小部件,但在核心上它只是一个BroadcastReceiver。
我是这样解决的:
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))
{
Log.d(TAG, "ACTION_RESTART_SERVICE... Restarting service with designated update interval...");
Intent i = new Intent(context, UpdateWidgetService.class);
service = startService(i, context, service);
} else
{
Log.d(TAG, "Not ACTION_RESTART_SERVICE... calling superclass onReceive()...");
super.onReceive(context, intent);
}
}
}
而在您的 Activity/Fragment 中:
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)
{
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);
}
看起来有点复杂,因为我有一个具有JellyBean动态可调整大小的小部件和低于该OS版本的固定小部件大小,但解决方案应该很清晰。
甚至更简单的解决方案可能是只需发送android.appwidget.action.APPWIDGET_UPDATE广播意图,就像启动器一样直接触发WidgetProvider的onUpdate()。
然后还有另一种完全不同的选择:让Updateservice自己获取WidgetIDs,因此无需从更新意图中获取它们。如果所有小部件基本上共享相同的配置,并且如果任何配置更改,则应更新所有小部件,则这是可以的:
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;
}
是的,我应该使用ArrayUtils将数组组合在一起... 这留下了改进的空间;-)