2010-08-25 93 views
9

想要我的小部件中的按钮触发小部件类上的APPWIDGET_UPDATE意图来强制更新,但我没有将APPWIDGET_UPDATE看作Intent中的静态字段。是否有可能以编程方式抛出APPWIDGET_UPDATE的意图?

这是可能的,以及如何做到这一点?

Intent intent = new Intent(context, BaseWidgetProvider.class); 
intent.setAction({APPWIDGET_UPDATE INTENT HERE}) 
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); 

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

回答

15

是的,这是可能的。你会在AppWidgetManager找到行动:

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE)

编辑:您将需要提供您要更新的控件的ID。以下是一个完整的示例。

AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); 
ComponentName widgetComponent = new ComponentName(context, YourWidget.class); 
int[] widgetIds = widgetManager.getAppWidgetIds(widgetComponent); 
Intent update = new Intent(); 
update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds); 
update.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); 
context.sendBroadcast(update); 
+0

谢谢。我在adb logcat中看到了意图触发器,但小部件不会更新。还有什么我应该做的?我的APPWIDGET_UPDATE已经作为我的清单文件中的intent过滤器了。 – NPike 2010-08-25 21:12:23

+0

'onUpdate()'不被调用?我必须就此回复你。 – Justin 2010-08-28 13:36:17

+0

您将需要提供更新的小部件的ID。如果你想更新你的小部件的所有实例,你可以从'AppWidgetManager'获得一个完整的id列表(我编辑了我的注释以包含代码)。 – Justin 2010-08-30 19:13:56

2

我知道这是一个很老的问题,但我认为这可能很有趣,因为Android更新了AppWidgets刷新策略。我认为这种改变可能会阻止现有的答案按预期工作。

这是我的解决方案,使用RemoteViews和一个集合。

public static final String ACTION_WIDGET_UPDATE = "com.yourpackage.widget.ACTION_UPDATE"; 

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
@Override 
public void onReceive(Context context, Intent intent) { 
    if (intent.getAction().equals(ACTION_WIDGET_UPDATE)) { 
     int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); 
     AppWidgetManager.getInstance(context) 
       .notifyAppWidgetViewDataChanged(widgetId, R.id.widgetColectionRoot); 
    } 
    super.onReceive(context, intent); 
} 

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
        int[] appWidgetIds) { 
    super.onUpdate(context, appWidgetManager, appWidgetIds); 
    for (int widgetId : appWidgetIds) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      RemoteViews collectionRemoteView = getRemoteViews(widgetId, context); 
      appWidgetManager.updateAppWidget(widgetId, collectionRemoteView); 
     } 

    } 
} 

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
@SuppressWarnings("deprecation") 
private RemoteViews getRemoteViews(int widgetId, Context context) { 
    // Sets up the intent that points to the RemoteViewService 
    // that will 
    // provide the views for this collection. 
    Intent widgetUpdateServiceIntent = new Intent(context, 
      RemoteViewsService.class); 
    widgetUpdateServiceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); 
    // When intents are compared, the extras are ignored, so we need 
    // to embed the extras 
    // into the data so that the extras will not be ignored. 
    widgetUpdateServiceIntent.setData(
      Uri.parse(widgetUpdateServiceIntent.toUri(Intent.URI_INTENT_SCHEME))); 
    RemoteViews collectionRemoteView = new RemoteViews(context.getPackageName(), 
      R.layout.widget_collection); 
    collectionRemoteView.setRemoteAdapter(widgetId, 
      R.id.widgetColectionRoot, widgetUpdateServiceIntent); 

    collectionRemoteView.setEmptyView(R.id.widgetColectionRoot, R.id.widgetEmpty); 

    // This section makes it possible for items to have 
    // individualized behavior. 
    // It does this by setting up a pending intent template. 
    // Individuals items of a collection 
    // cannot set up their own pending intents. Instead, the 
    // collection as a whole sets 
    // up a pending intent template, and the individual items set a 
    // fillInIntent 
    // to create unique behavior on an item-by-item basis. 
    Intent selectItemIntent = new Intent(context, 
      BrochuresWidgetProvider.class); 

    Intent refreshIntent = new Intent(selectItemIntent); 
    refreshIntent.setAction(ACTION_WIDGET_UPDATE); 
    PendingIntent refreshPendingIntent = PendingIntent.getBroadcast(
      context, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
    collectionRemoteView.setOnClickPendingIntent(R.id.widgetReload, 
      refreshPendingIntent); 
    return collectionRemoteView; 
} 

当然,你还需要注册的意图过滤器在你的清单,你的控件提供的声明中。

相关问题