Question

I'm trying to make work a self-updating functionality in an Android widget, something simple as changing two TextViews of it every 10 seconds. The ideal solution would be to make it similar to the genie widget (news & weather). And so far, it works okay: it updates every 10 seconds via Handler.postDelayed's Runnable.

Runnable updateWidgetText = new Runnable()
{
    @Override
    public void run() {
        if (screenEnabled) {
            AppWidgetManager gm = AppWidgetManager.getInstance(ctx);                        
            ComponentName thisWidget = new ComponentName(ctx,AnimeUndergroundWidget.class);         

            int index = (int)(REFRESH_COUNT % WIDGET_NEWS_TO_SHOW);
            Noticia n = AUnder.single().getNoticiaByIndex(index);
            if (n!=null)
            {
                last = n;
                RemoteViews views = new RemoteViews(ctx.getPackageName(),R.layout.auwidget);    
                views.setTextViewText(R.id.widget_textview, n.getTitulo());
                views.setTextViewText(R.id.widget_textototal, n.getTexto().replace("\n", ""));  

                Intent clickintent = new Intent(INTENT_GO_TO_NEW);
                PendingIntent pendingIntentClick = PendingIntent.getBroadcast(ctx, 0, clickintent, 0);
                views.setOnClickPendingIntent(R.id.widget_fondo_titulo, pendingIntentClick);

                Intent click2intent = new Intent(INTENT_GO_TO_NEW);
                PendingIntent pendingIntentClick2 = PendingIntent.getBroadcast(ctx, 0, click2intent, 0);
                views.setOnClickPendingIntent(R.id.widget_fondo_Texto, pendingIntentClick2);

                gm.updateAppWidget(thisWidget, views);
            }
            REFRESH_COUNT++;
        }

        handler.removeCallbacks(this);
        handler.postDelayed(this, WIDGET_REFRESH_TIME*1000);
    }   
};  

The runnable is initially launched in the onUpdate method of my Widget class:

    @Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    ctx = context;
    context.startService(new Intent(context, UpdateWidgetService.class));   
    handler.postDelayed(updateWidgetText,WIDGET_REFRESH_TIME*1000);
// here goes some more code, updating the views and refreshing click intents
}

I put this in case someone finds it useful.

But let me go straight to the point: when I get the phone out of sleep (turn on the screen), the widget goes crazy and starts changing the TextViews with a fastforward-like effect. I assume it is because there are some postDelayed events in queue, or may be in the updateAppWidget queue. I've already tried a workaround using the code shown in here: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/ You can see it in the first snippet in my code, I check a boolean variable that has stored screen state to avoid using postDelayed when the screen is turned off. But that doesn't seem to fix it.

This problem is driving me crazy for one week now, so I ask out of despair: is there any way to do this properly?

Was it helpful?

Solution

Your postDelayed call isn't inside your if (screenEnabled) block, so it will continue to post the events even when the screenEnabled is false

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top