Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to throw an intent for APPWIDGET_UPDATE programmatically?

Tags:

android

Would like a button in my widget to fire the APPWIDGET_UPDATE intent on the widget class to force an update, but I dont see APPWIDGET_UPDATE as a static field in Intent.

Is this possible, and how would one do this?

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);
like image 264
NPike Avatar asked Aug 25 '10 20:08

NPike


2 Answers

Yes, it's possible. You'll find the action in AppWidgetManager:

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE)

Edit: You will need to provide the ids of the widgets you want to update. Below is a complete sample.

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);
like image 163
Justin Avatar answered Oct 18 '22 23:10

Justin


I know this is a very old question, but I think this might be interesting, because Android updated the AppWidgets refresh policies. I think this change could prevent the exising answer to work as expected.

This is my solution, using RemoteViews and a collection.

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;
}

Of course, you also need to register that intent-filter on your manifest, inside your widget provider declaration.

like image 29
mdelolmo Avatar answered Oct 18 '22 21:10

mdelolmo