Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Properly Update AppWidget?

I'm a noob to android and I'm having issues updating an appwidget. It's a news widget that displays different text every 20 secs. I have no problem getting the text to switch & display properly when the widget is initialized. However, after every 30 min update of the widget my widgetID int array retains the int that existed prior to the update. So after each update the widget shows old data and new data. Is there a to clear the widget ID int array of old data during the update process. Any help is greatly appreciated.

My Code:

allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);

Method for switching text in widget. This works fine initially, but after update shows old data along with new data...

   public void updateStory() {

    tickerheadline = RssReader.rssheadline.get(storyCounter);
    tickerstory = RssReader.rssstory.get(storyCounter);
    remoteViews.setTextViewText(R.id.headline, tickerheadline );
    remoteViews.setTextViewText(R.id.story, tickerstory );
    if (storyCounter==RssReader.rssheadline.size()-1){
        storyCounter = 0;
        storyCounter++;
    }else{
        storyCounter++;
    }
    appWidgetManager.updateAppWidget(allWidgetIds, remoteViews); 
    //Log.e("Widget", allWidgetIds.toString());
    mHandler.postDelayed(new Runnable() { 
         public void run() { 
           updateStory(); 
         } } ,20000);  }

}

EDIT

public void updateStory() {
    //Added
    appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
    ComponentName thisWidget = new ComponentName(getApplicationContext(),MyWidgetProvider.class);
    remoteViews = new RemoteViews(this.getApplicationContext().getPackageName(),R.layout.widget1);    


    tickerheadline = RssReader.rssheadline.get(storyCounter);
    tickerstory = RssReader.rssstory.get(storyCounter);
    remoteViews.setTextViewText(R.id.headline, tickerheadline );
    remoteViews.setTextViewText(R.id.story, tickerstory );
    if (storyCounter==RssReader.rssheadline.size()-1){
        storyCounter = 0;
        storyCounter++;
    }else{
        storyCounter++;
    }



    appWidgetManager.updateAppWidget(thisWidget, remoteViews); 

    //appWidgetManager.updateAppWidget(allWidgetIds, remoteViews); 
    //Log.e("Widget", allWidgetIds.toString());
    mHandler.postDelayed(new Runnable() { 
         public void run() { 
           updateStory(); 
         } } ,20000);  }

}
like image 760
B. Money Avatar asked Feb 21 '13 16:02

B. Money


People also ask

How do you update 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.


1 Answers

Although you can be very clever with AppWidgets in android in terms of updating and so in, the easiest way to get going is simply to rebuild the widget contents every time you refresh. As you're only refreshing every 30 minutes, there's not much reason to worry about cpu usage.

So, I would suggest doing a standard rebuild each time you trigger an update using the standard approach. The code you have above, whilst it looks correct, doesn't actually force an update, much cleaner to start from scratch. Once that's working, then if you can make it more lightweight, do tell me how!

// You need to provide:
// myContext - the Context it is being run in.
// R.layout.widget - the xml layout of the widget
// All the content to put in it (duh!)
// Widget.class - the class for the widget

RemoteViews rv= new RemoteViews(myContext.getPackageName(), R.layout.widget);
rv.setXXXXXXX // as per normal using most recent data set.
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(myContext);
// If you know the App Widget Id use this:
appWidgetManager.updateAppWidget(appWidgetId, rv);
// Or to update all your widgets with the same contents:
ComponentName projectWidget = new ComponentName(myContext, Widget.class);
appWidgetManager.updateAppWidget(projectWidget, rv);

Often the easiest approach (in my view) is to wrap this up in a WidgetUpdater.class which you either call from a service or directly using a time alarm call. Using onUpdate is generally a bad idea because it force the phone into full power mode and isn't very controllable. I've never managed to make it work. Much better to do something like:

    Intent myIntent = // As per your onUpdate Code
    alarmPendingIntent = PendingIntent.getService(context, 0, myIntent, PendingIntent.FLAG_ONE_SHOT);

    // ... using the alarm manager mechanism.
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTimeMillis, alarmPendingIntent);
like image 53
Neil Townsend Avatar answered Sep 18 '22 12:09

Neil Townsend