I've written a simple clock widget which displays the current time on
the home screen. I created an AppWidgetProvider class, which overrides
the onReceive() and onEnabled() methods. In addition, I created a
Service class that creates a Timer, which polls the system clock each
second to see if the time has change, and if it has, it broadcasts a
update clock intent that is registered by the AppWidgetProvider.
According to the log, all of these methods work as the should, but the
display for the widget doesn't update. Normally, it only shows the
default display 88:88, but occasionally it does actually update, but
this is a rare occurrence.

I wasn't sure if I should paste my code or not, but I thought it best
to do so because I'm not sure where the problem could be occurring. I
would really like to do this using my Service class because I'm
learning how to use them. Therefore, I'd be grateful if you could give
suggestions which allow me to use the Service class (in the right way
of course).

Here is my code (note: I'm coding for Android 1.6):

/** SimpleClock.java : AppWidgetProvider Class**/
package com.simpleclock.widget;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

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

public class SimpleClock extends AppWidgetProvider
{
  private static final String LOG_TAG = "SimpleClock";
  private static final String APPWIDGET_UPDATE =
"android.appwidget.action.APPWIDGET_UPDATE";
  static final String UPDATE_WIDGET =
"com.simpleclock.widget.UPDATE_WIDGET";
  private static final String APPWIDGET_DISABLED =
"android.appwidget.action.APPWIDGET_DISABLED";

  @Override
  public void onReceive(Context context, Intent intent)
  {
    super.onReceive(context, intent);
    Log.d(LOG_TAG, "onReceive(context, intent=" + intent.getAction() +
")");
    if (UPDATE_WIDGET.equals(intent.getAction())
        || APPWIDGET_UPDATE.equals(intent.getAction()))
    {
      ComponentName widget = new ComponentName(context,
SimpleClock.class);
      AppWidgetManager appWidgetManager =
AppWidgetManager.getInstance(context);
      int[] appWidgetIds = appWidgetManager.getAppWidgetIds(widget);
      RemoteViews remoteView = new
RemoteViews(context.getPackageName(),
          R.layout.date_under_2);
      Log.d(LOG_TAG, "  appWidgetIds = " + idsToString(appWidgetIds));
      this.updateView(remoteView);
      appWidgetManager.updateAppWidget(widget, remoteView);
    } else if (APPWIDGET_DISABLED.equals(intent.getAction()))
    {
      Intent stopClock = new Intent(context, ClockService.class);
      stopClock.putExtra(ClockService.ACTION, ClockService.STOP);
      context.stopService(stopClock);
    }
  }

  @Override
  public void onEnabled(Context context)
  {
    Log.d(LOG_TAG, "onEnabled(context)");
    Intent startClock = new Intent(context, ClockService.class);
    startClock.putExtra(ClockService.ACTION, ClockService.START);
    context.startService(startClock);
    super.onEnabled(context);
  }

  private void updateView(RemoteViews view)
  {
    final DateFormat timeFormat =
DateFormat.getTimeInstance(DateFormat.MEDIUM,
        Locale.UK);
    String time = timeFormat.format(new Date());

    final DateFormat dateFormat =
DateFormat.getDateInstance(DateFormat.MEDIUM,
        Locale.UK);
    String date = dateFormat.format(new Date());
    date = date.replace('-', ' ');

    final DateFormat dayFormat =
DateFormat.getDateInstance(DateFormat.FULL,
        Locale.UK);
    String dayDate = dayFormat.format(new Date());
    int comma = dayDate.lastIndexOf(',') + 1;
    dayDate = dayDate.substring(0, comma) + " " + date;

    Log.d(LOG_TAG, "updateView(view):");
    Log.d(LOG_TAG, "  time=" + time + ", dayDate=" + dayDate);
    time = time.substring(0, 5);

    view.setTextViewText(R.id.time, time);
    view.setTextViewText(R.id.dayDate, dayDate);
  }

  private String idsToString(int[] appWidgetIds)
  {
    String ids = "[";
    for (int i = 0; i < appWidgetIds.length; i++)
    {
      if (i == appWidgetIds.length - 1)
        ids += appWidgetIds[i];
      else
        ids += appWidgetIds[i] + ", ";
    }
    ids += "]";
    return ids;
  }
}


/** ClockService.java : Service class **/
package com.simpleclock.widget;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class ClockService extends Service
{
  private static final String LOG_TAG = "ClockService";
  public static final String ACTION = "com.simpleclock.widget.ACTION";
  public static final int START = 0;
  public static final int STOP = 1;
  private static long updatePeriod = 1000; // 1 second = 1000
milliseconds
  private int lastMinute = 0;
  private Timer timer = new Timer("com.simpleclock.widget.TIMER");

  private TimerTask updateClock = new TimerTask()
  {
    public void run()
    {
      final DateFormat timeFormat = DateFormat.getTimeInstance(
          DateFormat.MEDIUM, Locale.UK);
      final String time = timeFormat.format(new Date());
      int minute = Integer.valueOf(time.substring(3, 5));

      if (minute != lastMinute)
      {
        sendBroadcast(new Intent(SimpleClock.UPDATE_WIDGET));
        lastMinute = minute;
        Log.d(LOG_TAG, "updateClock: ");
        Log.d(LOG_TAG, "  time=" + time + ", minute=" + minute
            + ", lastMinute=" + lastMinute);
      }
    }
  };

  @Override
  public void onCreate()
  {
    Log.d(LOG_TAG, "onCreate()");
    Log.d(LOG_TAG, "  timer.scheduleAtFixedRate(updateClock, 0,
updatePeriod="
        + updatePeriod);
    timer.scheduleAtFixedRate(updateClock, 0, updatePeriod);
  }

  @Override
  public void onDestroy()
  {
    Log.d(LOG_TAG, "onDestroy()");
    timer.cancel();
    Log.d(LOG_TAG, "timer.cancel()");
    super.onDestroy();
  }

  @Override
  public IBinder onBind(Intent intent)
  {
    return null;
  }

  @Override
  public void onStart(Intent intent, int startId)
  {
    Log.d(LOG_TAG, "ClockService.onStart(intent=" + intent.getAction()
        + ", startId=" + startId);
    if (ACTION.equals(intent.getAction()))
    {
      final int action = intent.getIntExtra(ACTION, 0);
      if (action == STOP)
      {
        onDestroy();
      }
    }
    super.onStart(intent, startId);
  }
}

<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android";
  package="com.simpleclock.widget"
  android:versionCode="1"
  android:versionName="1.0">
  <application
    android:icon="@drawable/icon"
    android:debuggable="true"
    android:label="@string/app_name">
    <service
      android:enabled="true"
      android:name=".ClockService" />
    <receiver
      android:name=".SimpleClock"
      android:label="@string/app_name">
      <intent-filter
        android:label="APPWIDGET_UPDATE">
        <action
          android:name="android.appwidget.action.APPWIDGET_UPDATE" />
      </intent-filter>
      <intent-filter
        android:label="UPDATE_WIDGET">
        <action
          android:name="com.simpleclock.widget.UPDATE_WIDGET" />
      </intent-filter>
      <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/simple_clock_provider" />
    </receiver>
  </application>
  <uses-sdk
    android:minSdkVersion="4"
    android:targetSdkVersion="4" />
</manifest>

<!-- simple_clock_provider.xml -->
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android";
  android:minWidth="146dip"
  android:minHeight="72dip"
  android:updatePeriodMillis="3600000"
  android:initialLayout="@layout/date_under_2" />
<!-- Updates every hour, though the service class should force it to
update every minute -->

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to