views:

296

answers:

1

I have a widget that you press and it then it will update the text on the widget. I have set an on click listener to launch another activity to perform the text update, But for some reason it only works temporarily and then it will become unresponsive and not do anything when pressed. Does anyone know why it might be doing that? i have posted my widget code below in case it is helpful.

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
    thisWidget = new ComponentName(context, MemWidget.class);
    Intent intent = new Intent(context, updatewidget.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

    // Get the layout for the App Widget and attach an on-click listener to the button
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
    views.setOnClickPendingIntent(R.id.ImageButton01, pendingIntent);

    // Tell the AppWidgetManager to perform an update on the current App Widget
    appWidgetManager.updateAppWidget(thisWidget, views);

}

@Override
public void onReceive(Context context, Intent intent) 
{
    appWidgetManager = AppWidgetManager.getInstance(context);
    remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
    thisWidget = new ComponentName(context, MemWidget.class);

    // v1.5 fix that doesn't call onDelete Action
    final String action = intent.getAction();
    if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
        final int appWidgetId = intent.getExtras().getInt(
            AppWidgetManager.EXTRA_APPWIDGET_ID,
            AppWidgetManager.INVALID_APPWIDGET_ID);
            if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
                this.onDeleted(context, new int[] { appWidgetId });
            }
        } 
    else 
    {   
        super.onReceive(context, intent);
    }
}

Here is code that is called from my activity

thisWidget = new ComponentName(this, MemWidget.class);
appWidgetManager = AppWidgetManager.getInstance(this);
remoteViews = new RemoteViews(this.getPackageName(), R.layout.widget);

//do work

remoteViews.setTextViewText(R.id.ImageButton01,"setting text here");
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
A: 

The onUpdate method there doesn't update any of the data in the RemoteViews other than the PendingIntent, so if that's ever called, the widget will revert to the state defined in R.layout.widget.

Do you have the code that calls updateAppWidget after the user interaction? That might help too.

Also, if the update is inline and doesn't require any UI, you don't need to launch an activity to do that update. It's more efficient and won't disrupt the back stack if your PendingIntent is for a broadcast receiver instead, using PendingIntent.getBroadcast. You can use the same BroadcastReceiver that is your app widget provider. You don't need another one.


Update: (I can't reply below because the text is too long)

I'd make a function like this, and call it from your activity from onUpdate(). You'll need to save text somewhere so you can also pass it in from onUpdate(). Otherwise it will revert the text to the default in R.layout.widget.

void updateWidget(Context context, CharSequence text) {
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);

    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
    remoteViews.setOnClickPendingIntent(R.id.ImageButton01, pendingIntent);

    remoteViews.setTextViewText(R.id.ImageButton01, text);

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName thisWidget = new ComponentName(context, MemWidget.class);
    appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
joeo
thanks for the response. I have added the code that calls updateappwidget after the user interaction from the launched activity. I will change the widget to use a broadcastreceiver instead of launching an activity, which isnt necessary. While looking for a solution I found this answer "Make sure I'm sending all PendingIntents across with each RemoteViews update, even if they've already been set. When the orientation changes, the layout is inflated and only the most-recently cached RemoteViews is applied over it."but how do I do that?
John
Thanks, it worked!
John