15c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson/*
25c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * Copyright (C) 2012 The Android Open Source Project
35c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson *
45c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * Licensed under the Apache License, Version 2.0 (the "License"); you may not
55c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * use this file except in compliance with the License. You may obtain a copy of
65c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * the License at
75c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson *
85c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * http://www.apache.org/licenses/LICENSE-2.0
95c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson *
105c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * Unless required by applicable law or agreed to in writing, software
115c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
125c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
135c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * License for the specific language governing permissions and limitations under
145c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson * the License.
155c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson */
165c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson
175c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonpackage com.android.alarmclock;
185c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson
199a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport android.app.AlarmManager;
205c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.app.PendingIntent;
215c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.appwidget.AppWidgetManager;
225c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.appwidget.AppWidgetProvider;
2369ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelsonimport android.appwidget.AppWidgetProviderInfo;
249a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport android.content.ComponentName;
255c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.content.Context;
265c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.content.Intent;
275c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.net.Uri;
285c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.os.Bundle;
299a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport android.provider.Settings;
309a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport android.text.TextUtils;
315579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelsonimport android.text.format.DateFormat;
329a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport android.util.Log;
339a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport android.view.View;
345c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport android.widget.RemoteViews;
355c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson
365c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport com.android.deskclock.DeskClock;
375c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport com.android.deskclock.R;
389a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport com.android.deskclock.Utils;
399a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport com.android.deskclock.alarms.AlarmNotifications;
409a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultasimport com.android.deskclock.worldclock.Cities;
4169ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelsonimport com.android.deskclock.worldclock.CitiesActivity;
425c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson
435579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelsonimport java.util.Locale;
445579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelson
455c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonpublic class DigitalAppWidgetProvider extends AppWidgetProvider {
469a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    private static final String TAG = "DigitalAppWidgetProvider";
479a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
489a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    /**
499a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * Intent to be used for checking if a world clock's date has changed. Must be every fifteen
509a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * minutes because not all time zones are hour-locked.
519a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     **/
529a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    public static final String ACTION_ON_QUARTER_HOUR = "com.android.deskclock.ON_QUARTER_HOUR";
539a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
549a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    // Lazily creating this intent to use with the AlarmManager
559a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    private PendingIntent mPendingIntent;
569a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    // Lazily creating this name to use with the AppWidgetManager
579a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    private ComponentName mComponentName;
589a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
595c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    public DigitalAppWidgetProvider() {
605c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    }
615c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson
625c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    @Override
639a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    public void onEnabled(Context context) {
649a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        super.onEnabled(context);
659a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        startAlarmOnQuarterHour(context);
669a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
679a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
689a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    @Override
699a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    public void onDisabled(Context context) {
709a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        super.onDisabled(context);
719a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        cancelAlarmOnQuarterHour(context);
729a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
739a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
749a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    @Override
759a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    public void onReceive(Context context, Intent intent) {
769a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        String action = intent.getAction();
779a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (DigitalAppWidgetService.LOGGING) {
789a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            Log.i(TAG, "onReceive: " + action);
799a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
809a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        super.onReceive(context, intent);
819a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
829a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (ACTION_ON_QUARTER_HOUR.equals(action)
839a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                || Intent.ACTION_DATE_CHANGED.equals(action)
849a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                || Intent.ACTION_TIMEZONE_CHANGED.equals(action)
859a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                || Intent.ACTION_TIME_CHANGED.equals(action)
869a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                || Intent.ACTION_LOCALE_CHANGED.equals(action)) {
879a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
889a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (appWidgetManager != null) {
899a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                int[] appWidgetIds = appWidgetManager.getAppWidgetIds(getComponentName(context));
909a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                for (int appWidgetId : appWidgetIds) {
919a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    appWidgetManager.
929a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                            notifyAppWidgetViewDataChanged(appWidgetId,
939a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                                    R.id.digital_appwidget_listview);
949a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    RemoteViews widget = new RemoteViews(context.getPackageName(),
959a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                            R.layout.digital_appwidget);
969a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    float ratio = WidgetUtils.getScaleRatio(context, null, appWidgetId);
97f9c17a244f7ac320808b45cf4d9d4bbe8c5343c0Isaac Katzenelson                    WidgetUtils.setTimeFormat(widget, 0/*no am/pm*/, R.id.the_clock);
989a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    WidgetUtils.setClockSize(context, widget, ratio);
999a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    refreshAlarm(context, widget);
1009a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    appWidgetManager.partiallyUpdateAppWidget(appWidgetId, widget);
1019a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                }
1029a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
1039a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if(!ACTION_ON_QUARTER_HOUR.equals(action)) {
1049a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                cancelAlarmOnQuarterHour(context);
1059a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
1069a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            startAlarmOnQuarterHour(context);
1079a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        } else if (AlarmNotifications.SYSTEM_ALARM_CHANGE_ACTION.equals(action)
1089a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                || Intent.ACTION_SCREEN_ON.equals(action)) {
1099a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            // Refresh the next alarm
1109a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
1119a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (appWidgetManager != null) {
1129a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                int[] appWidgetIds = appWidgetManager.getAppWidgetIds(getComponentName(context));
1139a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                for (int appWidgetId : appWidgetIds) {
1149a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    RemoteViews widget = new RemoteViews(context.getPackageName(),
1159a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                            R.layout.digital_appwidget);
1169a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    refreshAlarm(context, widget);
1179a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    appWidgetManager.partiallyUpdateAppWidget(appWidgetId, widget);
1189a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                }
1199a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
1209a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        } else if (Cities.WORLDCLOCK_UPDATE_INTENT.equals(action)) {
1219a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            // Refresh the world cities list
1229a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
1239a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (appWidgetManager != null) {
1249a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                int[] appWidgetIds = appWidgetManager.getAppWidgetIds(getComponentName(context));
1259a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                for (int appWidgetId : appWidgetIds) {
1269a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    appWidgetManager.
1279a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                            notifyAppWidgetViewDataChanged(appWidgetId,
1289a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                                    R.id.digital_appwidget_listview);
1299a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                }
1309a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
1319a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
1329a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
1339a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
1349a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    @Override
13572f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
1369a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (DigitalAppWidgetService.LOGGING) {
1379a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            Log.i(TAG, "onUpdate");
1389a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
1395c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        for (int appWidgetId : appWidgetIds) {
14072f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas            float ratio = WidgetUtils.getScaleRatio(context, null, appWidgetId);
14172f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas            updateClock(context, appWidgetManager, appWidgetId, ratio);
1425c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        }
1439a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        startAlarmOnQuarterHour(context);
14472f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        super.onUpdate(context, appWidgetManager, appWidgetIds);
1455c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    }
1465c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson
1475c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    @Override
1485c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
1495c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson            int appWidgetId, Bundle newOptions) {
1505c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        // scale the fonts of the clock to fit inside the new size
15103b136413ea5d5ef92f2f1286fb177205da3b1ebItzhak Katzenelson        float ratio = WidgetUtils.getScaleRatio(context, newOptions, appWidgetId);
1525c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
1535c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        updateClock(context, widgetManager, appWidgetId, ratio);
1545c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    }
1555c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson
1565c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    private void updateClock(
15772f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas            Context context, AppWidgetManager appWidgetManager, int appWidgetId, float ratio) {
15872f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.digital_appwidget);
15972f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas
16072f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        // Launch clock when clicking on the time in the widget only if not a lock screen widget
16169ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelson        Bundle newOptions = appWidgetManager.getAppWidgetOptions(appWidgetId);
16269ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelson        if (newOptions != null &&
16369ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelson                newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1)
16469ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelson                != AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) {
16569ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelson            widget.setOnClickPendingIntent(R.id.digital_appwidget,
16672f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas                    PendingIntent.getActivity(context, 0, new Intent(context, DeskClock.class), 0));
16769ba4ed9235ad2a77177629bac241ab0e6915087Isaac Katzenelson        }
16872f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas
169f9c17a244f7ac320808b45cf4d9d4bbe8c5343c0Isaac Katzenelson        // Setup alarm text clock's format and font sizes
1709a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        refreshAlarm(context, widget);
171f9c17a244f7ac320808b45cf4d9d4bbe8c5343c0Isaac Katzenelson        WidgetUtils.setTimeFormat(widget, 0/*no am/pm*/, R.id.the_clock);
17272f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        WidgetUtils.setClockSize(context, widget, ratio);
17372f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas
1745579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelson        // Set today's date format
1755579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelson        CharSequence dateFormat = DateFormat.getBestDateTimePattern(Locale.getDefault(),
1765579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelson                context.getString(R.string.abbrev_wday_month_day_no_year));
1775579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelson        widget.setCharSequence(R.id.date, "setFormat12Hour", dateFormat);
1785579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelson        widget.setCharSequence(R.id.date, "setFormat24Hour", dateFormat);
1795579584ad5ebf4498d7404cdc062b7d216670ed5Isaac Katzenelson
18072f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        // Set up R.id.digital_appwidget_listview to use a remote views adapter
18172f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        // That remote views adapter connects to a RemoteViewsService through intent.
18272f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        final Intent intent = new Intent(context, DigitalAppWidgetService.class);
1835c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
1845c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
18572f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        widget.setRemoteAdapter(R.id.digital_appwidget_listview, intent);
18672f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas
18772f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        // Set up the click on any world clock to start the Cities Activity
18872f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        //TODO: Should this be in the options guard above?
1895c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        widget.setPendingIntentTemplate(R.id.digital_appwidget_listview,
19072f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas                PendingIntent.
19172f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas                        getActivity(context, 0, new Intent(context, CitiesActivity.class), 0));
19272f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas
19372f83e2261f68f274ac8fbf9c4b8d0e23f00d376Robyn Coultas        // Refresh the widget
1945c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        appWidgetManager.notifyAppWidgetViewDataChanged(
1955c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson                appWidgetId, R.id.digital_appwidget_listview);
1965c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson        appWidgetManager.updateAppWidget(appWidgetId, widget);
1975c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    }
1989a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
1999a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    protected void refreshAlarm(Context context, RemoteViews widget) {
2009a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        String nextAlarm = Settings.System.getString(context.getContentResolver(),
2019a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                Settings.System.NEXT_ALARM_FORMATTED);
2029a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (!TextUtils.isEmpty(nextAlarm)) {
2039a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            widget.setTextViewText(R.id.nextAlarm,
2049a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    context.getString(R.string.control_set_alarm_with_existing, nextAlarm));
2059a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            widget.setViewVisibility(R.id.nextAlarm, View.VISIBLE);
2069a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (DigitalAppWidgetService.LOGGING) {
2079a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                Log.v(TAG, "DigitalWidget sets next alarm string to " + nextAlarm);
2089a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
2099a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        } else  {
2109a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            widget.setViewVisibility(R.id.nextAlarm, View.GONE);
2119a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (DigitalAppWidgetService.LOGGING) {
2129a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                Log.v(TAG, "DigitalWidget sets next alarm string to null");
2139a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
2149a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
2159a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
2169a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
2179a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    /**
2189a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * Start an alarm that fires on the next quarter hour to update the world clock city
2199a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * day when the local time or the world city crosses midnight.
2209a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     *
2219a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * @param context The context in which the PendingIntent should perform the broadcast.
2229a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     */
2239a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    private void startAlarmOnQuarterHour(Context context) {
2249a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (context != null) {
2259a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            long onQuarterHour = Utils.getAlarmOnQuarterHour();
2269a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            PendingIntent quarterlyIntent = getOnQuarterHourPendingIntent(context);
2279a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            AlarmManager alarmManager = ((AlarmManager) context
2289a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    .getSystemService(Context.ALARM_SERVICE));
2296ff2962d9a2726bacffa20ed09e3c3346fe7491dIsaac Katzenelson            if (Utils.isKitKatOrLater()) {
2309a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                alarmManager.setExact(AlarmManager.RTC, onQuarterHour, quarterlyIntent);
2319a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            } else {
2329a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                alarmManager.set(AlarmManager.RTC, onQuarterHour, quarterlyIntent);
2339a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
2349a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (DigitalAppWidgetService.LOGGING) {
2359a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                Log.v(TAG, "startAlarmOnQuarterHour " + context.toString());
2369a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
2379a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
2389a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
2399a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
2409a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
2419a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    /**
2429a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * Remove the alarm for the quarter hour update.
2439a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     *
2449a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * @param context The context in which the PendingIntent was started to perform the broadcast.
2459a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     */
2469a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    public void cancelAlarmOnQuarterHour(Context context) {
2479a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (context != null) {
2489a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            PendingIntent quarterlyIntent = getOnQuarterHourPendingIntent(context);
2499a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (DigitalAppWidgetService.LOGGING) {
2509a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                Log.v(TAG, "cancelAlarmOnQuarterHour " + context.toString());
2519a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
2529a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).cancel(
2539a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    quarterlyIntent);
2549a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
2559a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
2569a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
2579a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    /**
2589a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * Create the pending intent that is broadcast on the quarter hour.
2599a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     *
2609a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * @param context The Context in which this PendingIntent should perform the broadcast.
2619a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * @return a pending intent with an intent unique to DigitalAppWidgetProvider
2629a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     */
2639a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    private PendingIntent getOnQuarterHourPendingIntent(Context context) {
2649a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (mPendingIntent == null) {
2659a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            mPendingIntent = PendingIntent.getBroadcast(context, 0,
2669a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                new Intent(ACTION_ON_QUARTER_HOUR), PendingIntent.FLAG_CANCEL_CURRENT);
2679a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
2689a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        return mPendingIntent;
2699a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
2709a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
2719a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    /**
2729a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * Create the component name for this class
2739a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     *
2749a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * @param context The Context in which the widgets for this component are created
2759a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     * @return the ComponentName unique to DigitalAppWidgetProvider
2769a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas     */
2779a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    private ComponentName getComponentName(Context context) {
2789a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        if (mComponentName == null) {
2799a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            mComponentName = new ComponentName(context, getClass());
2809a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
2819a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        return mComponentName;
2829a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    }
2835c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson}
284