FileDocCategorySizeDatePackage
CalendarAppWidgetProvider.javaAPI DocAndroid 1.5 API10223Wed May 06 22:42:48 BST 2009com.android.providers.calendar

CalendarAppWidgetProvider

public class CalendarAppWidgetProvider extends android.appwidget.AppWidgetProvider
Simple widget to show next upcoming calendar event.

Fields Summary
static final String
TAG
static final boolean
LOGD
static final String
ACTION_CALENDAR_APPWIDGET_UPDATE
static final long
UPDATE_THRESHOLD
Threshold to check against when building widget updates. If system clock has changed less than this amount, we consider ignoring the request.
static final long
WAKE_LOCK_TIMEOUT
Maximum time to hold {@link WakeLock} when performing widget updates.
static final String
PACKAGE_THIS_APPWIDGET
static final String
CLASS_THIS_APPWIDGET
private static CalendarAppWidgetProvider
sInstance
Constructors Summary
Methods Summary
static android.content.ComponentNamegetComponentName(android.content.Context context)
Build {@link ComponentName} describing this specific {@link AppWidgetProvider}

        return new ComponentName(PACKAGE_THIS_APPWIDGET, CLASS_THIS_APPWIDGET);
    
static synchronized com.android.providers.calendar.CalendarAppWidgetProvidergetInstance()

    
        
        if (sInstance == null) {
            sInstance = new CalendarAppWidgetProvider();
        }
        return sInstance;
    
static android.app.PendingIntentgetUpdateIntent(android.content.Context context)
Build the {@link PendingIntent} used to trigger an update of all calendar widgets. Uses {@link #ACTION_CALENDAR_APPWIDGET_UPDATE} to directly target all widgets instead of using {@link AppWidgetManager#EXTRA_APPWIDGET_IDS}.

param
context Context to use when building broadcast.

        Intent updateIntent = new Intent(ACTION_CALENDAR_APPWIDGET_UPDATE);
        updateIntent.setComponent(new ComponentName(context, CalendarAppWidgetProvider.class));
        return PendingIntent.getBroadcast(context, 0 /* no requestCode */,
                updateIntent, 0 /* no flags */);
    
private booleanhasInstances(android.content.Context context)
Check against {@link AppWidgetManager} if there are any instances of this widget.

        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        ComponentName thisAppWidget = getComponentName(context);
        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
        return (appWidgetIds.length > 0);
    
public voidonDisabled(android.content.Context context)
{@inheritDoc}

        // Unsubscribe from all AlarmManager updates
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent pendingUpdate = getUpdateIntent(context);
        am.cancel(pendingUpdate);

        // Disable updates for timezone and date changes
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(
                new ComponentName(context, TimeChangeReceiver.class),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    
public voidonEnabled(android.content.Context context)
{@inheritDoc}

        // Enable updates for timezone and date changes
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(
                new ComponentName(context, TimeChangeReceiver.class),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    
public voidonReceive(android.content.Context context, android.content.Intent intent)
{@inheritDoc}

        // Handle calendar-specific updates ourselves because they might be
        // coming in without extras, which AppWidgetProvider then blocks.
        final String action = intent.getAction();
        if (ACTION_CALENDAR_APPWIDGET_UPDATE.equals(action)) {
            performUpdate(context, null /* all widgets */,
                    null /* no eventIds */, false /* don't ignore */);
        } else {
            super.onReceive(context, intent);
        }
    
public voidonUpdate(android.content.Context context, android.appwidget.AppWidgetManager appWidgetManager, int[] appWidgetIds)
{@inheritDoc}

        performUpdate(context, appWidgetIds, null /* no eventIds */, false /* force */);
    
private voidperformUpdate(android.content.Context context, int[] appWidgetIds, long[] changedEventIds, boolean considerIgnore)
Process and push out an update for the given appWidgetIds. This call actually fires an intent to start {@link CalendarAppWidgetService} as a background service which handles the actual update, to prevent ANR'ing during database queries.

This call will acquire a single {@link WakeLock} and set a flag that an update has been requested.

param
context Context to use when acquiring {@link WakeLock} and starting {@link CalendarAppWidgetService}.
param
appWidgetIds List of specific appWidgetIds to update, or null for all.
param
changedEventIds Specific events known to be changed. If present, we use it to decide if an update is necessary.
param
considerIgnore If true, compare {@link AppWidgetShared#sLastRequest} against {@link #UPDATE_THRESHOLD} to consider ignoring this update request.

        synchronized (AppWidgetShared.sLock) {
            // Consider ignoring this update request if inside threshold. This
            // check is inside the lock because we depend on this "now" time.
            long now = System.currentTimeMillis();
            if (considerIgnore && AppWidgetShared.sLastRequest != -1) {
                long delta = Math.abs(now - AppWidgetShared.sLastRequest);
                if (delta < UPDATE_THRESHOLD) {
                    if (LOGD) Log.d(TAG, "Ignoring update request because delta=" + delta);
                    return;
                }
            }
            
            // We need to update, so make sure we have a valid, held wakelock
            if (AppWidgetShared.sWakeLock == null ||
                    !AppWidgetShared.sWakeLock.isHeld()) {
                if (LOGD) Log.d(TAG, "no held wakelock found, so acquiring new one");
                PowerManager powerManager = (PowerManager)
                        context.getSystemService(Context.POWER_SERVICE);
                AppWidgetShared.sWakeLock =
                        powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
                AppWidgetShared.sWakeLock.setReferenceCounted(false);
                AppWidgetShared.sWakeLock.acquire(WAKE_LOCK_TIMEOUT);
            }
            
            if (LOGD) Log.d(TAG, "setting request now=" + now);
            AppWidgetShared.sLastRequest = now;
            AppWidgetShared.sUpdateRequested = true;
            
            // Apply filters that would limit the scope of this update, or clear
            // any pending filters if all requested.
            AppWidgetShared.mergeAppWidgetIdsLocked(appWidgetIds);
            AppWidgetShared.mergeChangedEventIdsLocked(changedEventIds);
            
            // Launch over to service so it can perform update
            final Intent updateIntent = new Intent(context, CalendarAppWidgetService.class);
            context.startService(updateIntent);
        }
    
voidproviderUpdated(android.content.Context context, long changedEventId)
The {@link CalendarProvider} has been updated, which means we should push updates to any widgets, if they exist.

param
context Context to use when creating widget.
param
changedEventId Specific event known to be changed, otherwise -1. If present, we use it to decide if an update is necessary.

        if (hasInstances(context)) {
            // Only pass along changedEventId if not -1
            long[] changedEventIds = null;
            if (changedEventId != -1) {
                changedEventIds = new long[] { changedEventId };
            }
            
            performUpdate(context, null /* all widgets */, changedEventIds, false /* force */);
        }
    
voidtimeUpdated(android.content.Context context, boolean considerIgnore)
{@link TimeChangeReceiver} has triggered that the time changed.

param
context Context to use when creating widget.
param
considerIgnore If true, compare {@link AppWidgetShared#sLastRequest} against {@link #UPDATE_THRESHOLD} to consider ignoring this update request.

        if (hasInstances(context)) {
            performUpdate(context, null /* all widgets */, null /* no events */, considerIgnore);
        }