163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson/*
263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * Copyright (C) 2012 The Android Open Source Project
363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson *
463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * Licensed under the Apache License, Version 2.0 (the "License");
563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * you may not use this file except in compliance with the License.
663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * You may obtain a copy of the License at
763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson *
863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson *      http://www.apache.org/licenses/LICENSE-2.0
963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson *
1063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * Unless required by applicable law or agreed to in writing, software
1163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * distributed under the License is distributed on an "AS IS" BASIS,
1263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * See the License for the specific language governing permissions and
1463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * limitations under the License.
1563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson */
1663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
1763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonpackage com.android.deskclock;
1863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
19d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzsteinimport android.app.Activity;
209814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultasimport android.content.BroadcastReceiver;
21421751e187dfa61bc1e48b52cdaf366628b06dd4Isaac Katzenelsonimport android.content.Context;
229814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultasimport android.content.Intent;
239814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultasimport android.content.IntentFilter;
2463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.content.SharedPreferences;
25fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelsonimport android.content.SharedPreferences.OnSharedPreferenceChangeListener;
26d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzsteinimport android.database.ContentObserver;
2763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.os.Bundle;
287bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzsteinimport android.os.Handler;
2963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.preference.PreferenceManager;
30d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzsteinimport android.provider.Settings;
3163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.view.LayoutInflater;
327bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzsteinimport android.view.MotionEvent;
3363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.view.View;
347bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzsteinimport android.view.View.OnTouchListener;
357bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzsteinimport android.view.ViewConfiguration;
3663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.view.ViewGroup;
37421751e187dfa61bc1e48b52cdaf366628b06dd4Isaac Katzenelsonimport android.widget.ListView;
3841bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelsonimport android.widget.TextClock;
3963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
401c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowskiimport com.android.deskclock.alarms.AlarmNotifications;
415c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelsonimport com.android.deskclock.worldclock.WorldClockAdapter;
4263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
4363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson/**
44d58f6c413eeb5bc138a4a97b56b25a6b22e20f22Itzhak Katzenelson * Fragment that shows  the clock (analog or digital), the next alarm info and the world clock.
4563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson */
46fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelsonpublic class ClockFragment extends DeskClockFragment implements OnSharedPreferenceChangeListener {
4763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
4863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private static final String BUTTONS_HIDDEN_KEY = "buttons_hidden";
499814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas    private final static String TAG = "ClockFragment";
5063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
51d58f6c413eeb5bc138a4a97b56b25a6b22e20f22Itzhak Katzenelson    private boolean mButtonsHidden = false;
52d58f6c413eeb5bc138a4a97b56b25a6b22e20f22Itzhak Katzenelson    private View mDigitalClock, mAnalogClock, mClockFrame;
53d58f6c413eeb5bc138a4a97b56b25a6b22e20f22Itzhak Katzenelson    private WorldClockAdapter mAdapter;
54d58f6c413eeb5bc138a4a97b56b25a6b22e20f22Itzhak Katzenelson    private ListView mList;
55d58f6c413eeb5bc138a4a97b56b25a6b22e20f22Itzhak Katzenelson    private SharedPreferences mPrefs;
566e47702790d5273012cb1c844c0bcf5462ea6194Itzhak Katzenelson    private String mDateFormat;
57932e0129e244e2874dfa3c6be58b2fe9a20cc89dSara Ting    private String mDateFormatForAccessibility;
587bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein    private String mDefaultClockStyle;
595c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson    private String mClockStyle;
60fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson
619814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
629814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas            @Override
639814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas        public void onReceive(Context context, Intent intent) {
6460f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson            String action = intent.getAction();
6560f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson            boolean changed = action.equals(Intent.ACTION_TIME_CHANGED)
6660f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson                    || action.equals(Intent.ACTION_TIMEZONE_CHANGED)
6760f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson                    || action.equals(Intent.ACTION_LOCALE_CHANGED);
689a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (changed) {
69c0d954df1479a0a1cc175db8238f74bd396abd28Isaac Katzenelson                Utils.updateDate(mDateFormat, mDateFormatForAccessibility,mClockFrame);
709814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas                if (mAdapter != null) {
71ef9888eabb6d299d8fe44cc66a7991ba7603a008Robyn Coultas                    // *CHANGED may modify the need for showing the Home City
729a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                    if (mAdapter.hasHomeCity() != mAdapter.needHomeCity()) {
7360f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson                        mAdapter.reloadData(context);
74ef9888eabb6d299d8fe44cc66a7991ba7603a008Robyn Coultas                    } else {
75ef9888eabb6d299d8fe44cc66a7991ba7603a008Robyn Coultas                        mAdapter.notifyDataSetChanged();
76ef9888eabb6d299d8fe44cc66a7991ba7603a008Robyn Coultas                    }
7741bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                    // Locale change: update digital clock format and
7841bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                    // reload the cities list with new localized names
7960f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson                    if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
8041bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                        if (mDigitalClock != null) {
8141bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                            Utils.setTimeFormat(
8241bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                                   (TextClock)(mDigitalClock.findViewById(R.id.digital_clock)),
8341bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                                   (int)context.getResources().
8441bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                                           getDimension(R.dimen.bottom_text_size));
8541bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                        }
8660f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson                        mAdapter.loadCitiesDb(context);
8760f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson                        mAdapter.notifyDataSetChanged();
8860f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson                    }
899814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas                }
909a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                Utils.setQuarterHourUpdater(mHandler, mQuarterHourUpdater);
919814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas            }
921c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski            if (changed || action.equals(AlarmNotifications.SYSTEM_ALARM_CHANGE_ACTION)) {
93c0d954df1479a0a1cc175db8238f74bd396abd28Isaac Katzenelson                Utils.refreshAlarm(getActivity(), mClockFrame);
94ef9888eabb6d299d8fe44cc66a7991ba7603a008Robyn Coultas            }
959814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas        }
969814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas    };
9763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
987bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein    private final Handler mHandler = new Handler();
997bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein
100d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein    private final ContentObserver mAlarmObserver = new ContentObserver(mHandler) {
101d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        @Override
102d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        public void onChange(boolean selfChange) {
103d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein            Utils.refreshAlarm(ClockFragment.this.getActivity(), mClockFrame);
104d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        }
105d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein    };
106d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein
1079a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    // Thread that runs on every quarter-hour and refreshes the date.
1089a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    private final Runnable mQuarterHourUpdater = new Runnable() {
1099a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        @Override
1109a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        public void run() {
1119a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            // Update the main and world clock dates
1129a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mClockFrame);
1139a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            if (mAdapter != null) {
1149a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas                mAdapter.notifyDataSetChanged();
1159a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            }
1169a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas            Utils.setQuarterHourUpdater(mHandler, mQuarterHourUpdater);
1179a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        }
1189a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas    };
1199a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas
12063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public ClockFragment() {
12163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
12263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
12363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    @Override
12463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public View onCreateView(LayoutInflater inflater, ViewGroup container,
12563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                             Bundle icicle) {
12663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        // Inflate the layout for this fragment
12763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        View v = inflater.inflate(R.layout.clock_fragment, container, false);
12863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        if (icicle != null) {
12963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mButtonsHidden = icicle.getBoolean(BUTTONS_HIDDEN_KEY, false);
13063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
131421751e187dfa61bc1e48b52cdaf366628b06dd4Isaac Katzenelson        mList = (ListView)v.findViewById(R.id.cities);
132421751e187dfa61bc1e48b52cdaf366628b06dd4Isaac Katzenelson        mList.setDivider(null);
13347b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein
13447b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        OnTouchListener longPressNightMode = new OnTouchListener() {
13547b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            private float mMaxMovementAllowed = -1;
13647b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            private int mLongPressTimeout = -1;
1377bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein            private float mLastTouchX, mLastTouchY;
1387bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein
1397bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein            @Override
1407bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein            public boolean onTouch(View v, MotionEvent event) {
14147b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein                if (mMaxMovementAllowed == -1) {
14247b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein                    mMaxMovementAllowed = ViewConfiguration.get(getActivity()).getScaledTouchSlop();
14347b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein                    mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
14447b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein                }
14547b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein
1467bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                switch (event.getAction()) {
1477bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                    case (MotionEvent.ACTION_DOWN):
1487bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        long time = Utils.getTimeNow();
1497bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        mHandler.postDelayed(new Runnable() {
1507bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                            @Override
1517bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                            public void run() {
1527bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                                startActivity(new Intent(getActivity(), ScreensaverActivity.class));
1537bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                            }
15447b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein                        }, mLongPressTimeout);
1557bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        mLastTouchX = event.getX();
1567bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        mLastTouchY = event.getY();
15747b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein                        return true;
1587bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                    case (MotionEvent.ACTION_MOVE):
1597bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        float xDiff = Math.abs(event.getX()-mLastTouchX);
1607bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        float yDiff = Math.abs(event.getY()-mLastTouchY);
16147b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein                        if (xDiff >= mMaxMovementAllowed || yDiff >= mMaxMovementAllowed) {
1627bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                            mHandler.removeCallbacksAndMessages(null);
1637bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        }
1647bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        break;
1657bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                    default:
1667bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                        mHandler.removeCallbacksAndMessages(null);
1677bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                }
1687bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                return false;
1697bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein            }
17047b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        };
17147b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein
17247b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        // On tablet landscape, the clock frame will be a distinct view. Otherwise, it'll be added
17347b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        // on as a header to the main listview.
17447b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        mClockFrame = v.findViewById(R.id.main_clock_left_pane);
17547b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        if (mClockFrame == null) {
17647b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            mClockFrame = inflater.inflate(R.layout.main_clock_frame, mList, false);
17747b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            mList.addHeaderView(mClockFrame, null, false);
17847b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        } else {
17947b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            // The main clock frame needs its own touch listener for night mode now.
18047b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            v.setOnTouchListener(longPressNightMode);
18147b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        }
18247b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        mList.setOnTouchListener(longPressNightMode);
18347b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein
184d968d6707f61078c3afacffa08c499ee9ed472a5Alan Viverette        // If the current layout has a fake overflow menu button, let the parent
185d968d6707f61078c3afacffa08c499ee9ed472a5Alan Viverette        // activity set up its click and touch listeners.
186d968d6707f61078c3afacffa08c499ee9ed472a5Alan Viverette        View menuButton = v.findViewById(R.id.menu_button);
187d968d6707f61078c3afacffa08c499ee9ed472a5Alan Viverette        if (menuButton != null) {
188d968d6707f61078c3afacffa08c499ee9ed472a5Alan Viverette            setupFakeOverflowMenuButton(menuButton);
189d968d6707f61078c3afacffa08c499ee9ed472a5Alan Viverette        }
190d968d6707f61078c3afacffa08c499ee9ed472a5Alan Viverette
19147b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        mDigitalClock = mClockFrame.findViewById(R.id.digital_clock);
19247b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        mAnalogClock = mClockFrame.findViewById(R.id.analog_clock);
19341bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson        Utils.setTimeFormat((TextClock)(mDigitalClock.findViewById(R.id.digital_clock)),
19441bfc41aec6b735f64d75ba79b85029dd5b0f6edIsaac Katzenelson                (int)getResources().getDimension(R.dimen.bottom_text_size));
19547b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        View footerView = inflater.inflate(R.layout.blank_footer_view, mList, false);
19647b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        footerView.setBackgroundResource(R.color.blackish);
19747b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        mList.addFooterView(footerView);
19847b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        mAdapter = new WorldClockAdapter(getActivity());
19947b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        mList.setAdapter(mAdapter);
2003bc02950da8c14ec04199043f41a9ffc13290c8dSam Blitzstein
201fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson        mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
2027bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein        mDefaultClockStyle = getActivity().getResources().getString(R.string.default_clock_style);
20363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        return v;
20463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
20563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
20663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    @Override
20763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public void onResume () {
20863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        super.onResume();
209fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson        mPrefs.registerOnSharedPreferenceChangeListener(this);
2106e47702790d5273012cb1c844c0bcf5462ea6194Itzhak Katzenelson        mDateFormat = getString(R.string.abbrev_wday_month_day_no_year);
211932e0129e244e2874dfa3c6be58b2fe9a20cc89dSara Ting        mDateFormatForAccessibility = getString(R.string.full_wday_month_day_no_year);
2129814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas
213d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        Activity activity = getActivity();
2149a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        Utils.setQuarterHourUpdater(mHandler, mQuarterHourUpdater);
215c0d954df1479a0a1cc175db8238f74bd396abd28Isaac Katzenelson        // Besides monitoring when quarter-hour changes, monitor other actions that
216c0d954df1479a0a1cc175db8238f74bd396abd28Isaac Katzenelson        // effect clock time
2179a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        IntentFilter filter = new IntentFilter();
2181c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski        filter.addAction(AlarmNotifications.SYSTEM_ALARM_CHANGE_ACTION);
2199814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas        filter.addAction(Intent.ACTION_TIME_CHANGED);
2209814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
22160f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
222d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        activity.registerReceiver(mIntentReceiver, filter);
2239814bd45c6c024c3646e7885f4004dfe1aa361e7Robyn Coultas
22460f175e2a226653bb240104c3cac6fc7d5043659Isaac Katzenelson        // Resume can invoked after changing the cities list or a change in locale
225421751e187dfa61bc1e48b52cdaf366628b06dd4Isaac Katzenelson        if (mAdapter != null) {
226d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein            mAdapter.loadCitiesDb(activity);
227d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein            mAdapter.reloadData(activity);
228421751e187dfa61bc1e48b52cdaf366628b06dd4Isaac Katzenelson        }
229fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson        // Resume can invoked after changing the clock style.
230d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        View clockView = Utils.setClockStyle(activity, mDigitalClock, mAnalogClock,
2317bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                SettingsActivity.KEY_CLOCK_STYLE);
2327bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein        mClockStyle = (clockView == mDigitalClock ?
2337bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein                Utils.CLOCK_TYPE_DIGITAL : Utils.CLOCK_TYPE_ANALOG);
23447b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein
23547b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        // Center the main clock frame if cities are empty.
23647b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        if (getView().findViewById(R.id.main_clock_left_pane) != null && mAdapter.getCount() == 0) {
23747b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            mList.setVisibility(View.GONE);
23847b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        } else {
23947b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein            mList.setVisibility(View.VISIBLE);
24047b10c08f7aaf2b2a28a5c66071b58c2707dad20Sam Blitzstein        }
2417bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein        mAdapter.notifyDataSetChanged();
2427bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein
243c0d954df1479a0a1cc175db8238f74bd396abd28Isaac Katzenelson        Utils.updateDate(mDateFormat, mDateFormatForAccessibility,mClockFrame);
244d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        Utils.refreshAlarm(activity, mClockFrame);
245d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        activity.getContentResolver().registerContentObserver(
246d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein                Settings.System.getUriFor(Settings.System.NEXT_ALARM_FORMATTED),
247d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein                false,
248d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein                mAlarmObserver);
24963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
25063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
251fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson    @Override
252fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson    public void onPause() {
253fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson        super.onPause();
254fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson        mPrefs.unregisterOnSharedPreferenceChangeListener(this);
2559a1057d6cd6eab416762ea0957c8c0e91bba28d4Robyn Coultas        Utils.cancelQuarterHourUpdater(mHandler, mQuarterHourUpdater);
256d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        Activity activity = getActivity();
257d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        activity.unregisterReceiver(mIntentReceiver);
258d42988e6e855a9775b9ebbbfa949ef90c5abf2cfSam Blitzstein        activity.getContentResolver().unregisterContentObserver(mAlarmObserver);
259fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson    }
26063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
26163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    @Override
26263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public void onSaveInstanceState (Bundle outState) {
26363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        outState.putBoolean(BUTTONS_HIDDEN_KEY, mButtonsHidden);
26463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        super.onSaveInstanceState(outState);
26563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
26663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
267fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson    @Override
268fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
269fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson        if (key == SettingsActivity.KEY_CLOCK_STYLE) {
2707bcc2d8ce2951a8f5451e93a5192b7ae04564de0Sam Blitzstein            mClockStyle = prefs.getString(SettingsActivity.KEY_CLOCK_STYLE, mDefaultClockStyle);
2715c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson            mAdapter.notifyDataSetChanged();
272fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson        }
273fc5cce3453c5b6c08814b1c1ba85612399466c0bIsaac Katzenelson    }
2745c464d35f230912053d7a5873dd6b59ca6e11852Isaac Katzenelson }
275