Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update Android Widget From Activity

I have a widget, its setup so that when I click on it, it opens some settings in an activity.

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

This configures some settings for the application. What I want to achieve is to have the widget update its view to reflect the changed settings when the Activity I launch closes. Using the update interval or any other type of polling isn't appropriate for this.

I've seen a couple places here and in the android docs this code used:

appWidgetManager.updateAppWidget(mAppWidgetId, views);

But I don't know how to get the mAppWidgetId value. I tried following the example for a widget configuration activity here http://developer.android.com/guide/topics/appwidgets/index.html, but in the following code,

    Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
    mAppWidgetId = extras.getInt(
            AppWidgetManager.EXTRA_APPWIDGET_ID, 
            AppWidgetManager.INVALID_APPWIDGET_ID);
}

extras is always null, so I never get the AppWidgetID.

Ok, now I'm just rambling. What do you think I can do?

like image 341
Kratz Avatar asked Nov 01 '10 23:11

Kratz


People also ask

How do you update Android widgets?

Full update: Call AppWidgetManager. updateAppWidget(int, android. widget. RemoteViews) to fully update the widget.

What is remote view in Android?

android.widget.RemoteViews. A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy.


3 Answers

I know this has been answered and accepted way ago. However while I was searching the same thing I came across an awesomely simple way to update the widget.

For future readers:

The best part, this works for all the instances of the widget and from any context (Activity, Service etc)

Heres the code,

Context context = this;
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_2x1);
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
remoteViews.setTextViewText(R.id.my_text_view, "myText" + System.currentTimeMillis());
appWidgetManager.updateAppWidget(thisWidget, remoteViews);

Courtesy - Stuck :)

like image 163
Atul O Holic Avatar answered Oct 11 '22 02:10

Atul O Holic


I finally found the answer I was looking for, it was in an overload of the updateAppWidget function.

   appWidgetManager.updateAppWidget(new ComponentName(this.getPackageName(), Widget.class.getName()), views);

This let me access the widget without having to know the appWidgetID. My final code in my activity is then:

        // Create an Intent to launch ExampleActivity
    Intent intent = new Intent(this, Settings.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

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

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
    appWidgetManager.updateAppWidget(new ComponentName(this.getPackageName(), Widget.class.getName()), views);
    finish();

I have to do all the same setup stuff I had to do in the onUpdate method of the Widget, but now every time I exit my activity the Widget is displaying the correct state.

like image 18
Kratz Avatar answered Oct 11 '22 02:10

Kratz


There's another way to do it - pass the widget id in the pending intent that you use to start the activity:

Intent clickIntent=new Intent(context, MyConfigActivity.class);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
// you have the widgetId here, since it's your onUpdate
PendingIntent pendingIntent=PendingIntent
        .getActivity(context, 0,
                clickIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.btnActivate, pendingIntent);

Moreover, to avoid duplication of code from onUpdate(), you can broadcast an intent back to the AppWidgetProvider:

Intent intent = new Intent(this,MyAppWidgetProvider.class);
intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");

// Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID,
// since it seems the onUpdate() is only fired on that:
int[] ids = {widgetId};
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
sendBroadcast(intent);
like image 14
phaethon Avatar answered Oct 11 '22 03:10

phaethon