Question

My Android widget is not updating the date.

It's a widget with only date, no more.

package com.android.widget;

import java.util.Timer;
import java.util.TimerTask;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.widget.RemoteViews;

public class MyCalendarWidget extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1,
                1000);
    }

    private class MyTime extends TimerTask {
        RemoteViews remoteViews;
        AppWidgetManager appWidgetManager;
        ComponentName thisWidget;
        Fecha fec = new Fecha();

        public MyTime(Context context, AppWidgetManager appWidgetManager) {
            this.appWidgetManager = appWidgetManager;
            remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
            thisWidget = new ComponentName(context, MyCalendarWidget.class);
        }

        @Override
        public void run() {
            remoteViews.setTextViewText(R.id.widget_textview, fec.DiaActual(false)+"\r\n"
                                                             +fec.DiaActual(true) +" de "
                                                             +fec.MesActual(false)+" de "
                                                             +fec.AñoActualNumerico());
            appWidgetManager.updateAppWidget(thisWidget, remoteViews);
        }
    }
}
Was it helpful?

Solution

Please begin by reading the documentation, AppWidget Guide and AppWidgetProvider. That explains:

  • Your onUpdate() method needs to send a RemoteViews to the widget via updateAppWidget().
  • Waking up once per second would drain your battery. You certainly don't want to update the widget while the phone is sleeping.
  • Each call to remoteViews.setTextViewText() appends more data to the RemoteViews object. That'll accumulate excess data in memory and make the widget slow. Instead, get a new RemoteViews instance each time.

My hypothesis about your updates not happening is the OS stopping your widget provider's component when the provider finishes responding to an Intent. You can test that hypothesis via Log.d().

You can register for an ACTION_TIME_TICK broadcast that tells you when the time changes, once per minute. Do test that it doesn't run when the phone sleeps (e.g. keep a count of calls) and feel free to report back here.

[Added] It's much easier in practice to display the date (and update it once per day) than the date + time (and update it once per minute; your question code tried to update it once per second), and to do this without using much battery power.

  • Set updatePeriodMillis="0".
  • Add <action android:name="android.intent.action.DATE_CHANGED"/> to the <intent-filter> for the widget provider in AndroidManifest.xml.
  • In the AppWidgetProvider, override

    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) { updateAllMyWidgets(context); }
    }
    
  • Use DateUtils.formatDateTime() to format the date.

Yes, the bug code.google.com/p/android/issues/detail?id=2880 will happen if the clock is adjusted backwards.

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