ClockFragment.java revision 3bc02950da8c14ec04199043f41a9ffc13290c8d
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.deskclock;
18
19import android.app.PendingIntent;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.content.SharedPreferences;
25import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
26import android.content.res.Configuration;
27import android.os.Bundle;
28import android.os.Handler;
29import android.preference.PreferenceManager;
30import android.view.Gravity;
31import android.view.LayoutInflater;
32import android.view.MotionEvent;
33import android.view.View;
34import android.view.View.OnTouchListener;
35import android.view.ViewConfiguration;
36import android.view.ViewGroup;
37import android.view.animation.AnimationUtils;
38import android.widget.FrameLayout;
39import android.widget.ImageView;
40import android.widget.ListView;
41
42import com.android.deskclock.worldclock.WorldClockAdapter;
43
44/**
45 * Fragment that shows  the clock (analog or digital), the next alarm info and the world clock.
46 */
47
48public class ClockFragment extends DeskClockFragment implements OnSharedPreferenceChangeListener {
49
50    private static final String BUTTONS_HIDDEN_KEY = "buttons_hidden";
51    private final static String TAG = "ClockFragment";
52
53    private boolean mButtonsHidden = false;
54    private View mDigitalClock, mAnalogClock, mClockFrame;
55    private WorldClockAdapter mAdapter;
56    private ListView mList;
57    private SharedPreferences mPrefs;
58    private String mDateFormat;
59    private String mDateFormatForAccessibility;
60    private String mDefaultClockStyle;
61    private String mClockStyle;
62
63    private PendingIntent mQuarterlyIntent;
64    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
65            @Override
66        public void onReceive(Context context, Intent intent) {
67            String action = intent.getAction();
68            boolean changed = action.equals(Intent.ACTION_TIME_CHANGED)
69                    || action.equals(Intent.ACTION_TIMEZONE_CHANGED)
70                    || action.equals(Intent.ACTION_LOCALE_CHANGED);
71            if (changed || action.equals(Utils.ACTION_ON_QUARTER_HOUR)) {
72                Utils.updateDate(mDateFormat, mDateFormatForAccessibility,mClockFrame);
73                if (mAdapter != null) {
74                    // *CHANGED may modify the need for showing the Home City
75                    if (changed && (mAdapter.hasHomeCity() != mAdapter.needHomeCity())) {
76                        mAdapter.reloadData(context);
77                    } else {
78                        mAdapter.notifyDataSetChanged();
79                    }
80                    // Reloading the cities list with new localized names
81                    if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
82                        mAdapter.loadCitiesDb(context);
83                        mAdapter.notifyDataSetChanged();
84                    }
85                }
86            }
87            if (changed || action.equals(Alarms.ALARM_DONE_ACTION)
88                    || action.equals(Alarms.ALARM_SNOOZE_CANCELLED)) {
89                Utils.refreshAlarm(getActivity(), mClockFrame);
90            }
91            if (changed) {
92                mQuarterlyIntent = Utils.refreshAlarmOnQuarterHour(getActivity(), mQuarterlyIntent);
93            }
94        }
95    };
96
97    private final Handler mHandler = new Handler();
98
99    public ClockFragment() {
100    }
101
102    @Override
103    public View onCreateView(LayoutInflater inflater, ViewGroup container,
104                             Bundle icicle) {
105        // Inflate the layout for this fragment
106        View v = inflater.inflate(R.layout.clock_fragment, container, false);
107        if (icicle != null) {
108            mButtonsHidden = icicle.getBoolean(BUTTONS_HIDDEN_KEY, false);
109        }
110        mList = (ListView)v.findViewById(R.id.cities);
111        mList.setDivider(null);
112        View headerView = inflater.inflate(R.layout.blank_header_view, mList, false);
113        mList.addHeaderView(headerView);
114        mClockFrame = inflater.inflate(R.layout.main_clock_frame, mList, false);
115        mDigitalClock = mClockFrame.findViewById(R.id.digital_clock);
116        mAnalogClock = mClockFrame.findViewById(R.id.analog_clock);
117        mList.addHeaderView(mClockFrame, null, false);
118        View footerView = inflater.inflate(R.layout.blank_footer_view, mList, false);
119        footerView.setBackgroundResource(R.color.blackish);
120        mList.addFooterView(footerView);
121        mAdapter = new WorldClockAdapter(getActivity());
122        mList.setAdapter(mAdapter);
123        mList.setOnTouchListener(new OnTouchListener() {
124            private final float MAX_MOVEMENT_ALLOWED = 20;
125            private float mLastTouchX, mLastTouchY;
126
127            @Override
128            public boolean onTouch(View v, MotionEvent event) {
129                switch (event.getAction()) {
130                    case (MotionEvent.ACTION_DOWN):
131                        long time = Utils.getTimeNow();
132                        mHandler.postDelayed(new Runnable() {
133                            @Override
134                            public void run() {
135                                startActivity(new Intent(getActivity(), ScreensaverActivity.class));
136                            }
137                        }, ViewConfiguration.getLongPressTimeout());
138                        mLastTouchX = event.getX();
139                        mLastTouchY = event.getY();
140                        break;
141                    case (MotionEvent.ACTION_MOVE):
142                        float xDiff = Math.abs(event.getX()-mLastTouchX);
143                        float yDiff = Math.abs(event.getY()-mLastTouchY);
144                        if (xDiff >= MAX_MOVEMENT_ALLOWED || yDiff >= MAX_MOVEMENT_ALLOWED) {
145                            mHandler.removeCallbacksAndMessages(null);
146                        }
147                        break;
148                    default:
149                        mHandler.removeCallbacksAndMessages(null);
150                }
151                return false;
152            }
153        });
154
155        // For landscape, put the cities button on the right and the menu in the actionbar.
156        View citiesButton = v.findViewById(R.id.cities_button);
157        View menuButton = v.findViewById(R.id.menu_button);
158        FrameLayout.LayoutParams layoutParams =
159                (FrameLayout.LayoutParams) citiesButton.getLayoutParams();
160        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
161            layoutParams.gravity = Gravity.END;
162            menuButton.setVisibility(View.GONE);
163        } else {
164            layoutParams.gravity = Gravity.CENTER;
165            menuButton.setVisibility(View.VISIBLE);
166        }
167        citiesButton.setLayoutParams(layoutParams);
168
169
170        mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
171        mDefaultClockStyle = getActivity().getResources().getString(R.string.default_clock_style);
172        return v;
173    }
174
175    @Override
176    public void onResume () {
177        super.onResume();
178        mPrefs.registerOnSharedPreferenceChangeListener(this);
179        mDateFormat = getString(R.string.abbrev_wday_month_day_no_year);
180        mDateFormatForAccessibility = getString(R.string.full_wday_month_day_no_year);
181
182        mQuarterlyIntent = Utils.startAlarmOnQuarterHour(getActivity());
183        // Besides monitoring when quarter-hour changes, monitor other actions that
184        // effect clock time
185        IntentFilter filter = new IntentFilter(Utils.ACTION_ON_QUARTER_HOUR);
186        filter.addAction(Alarms.ALARM_DONE_ACTION);
187        filter.addAction(Alarms.ALARM_SNOOZE_CANCELLED);
188        filter.addAction(Intent.ACTION_TIME_CHANGED);
189        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
190        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
191        getActivity().registerReceiver(mIntentReceiver, filter);
192
193        // Resume can invoked after changing the cities list or a change in locale
194        if (mAdapter != null) {
195            mAdapter.loadCitiesDb(getActivity());
196            mAdapter.reloadData(getActivity());
197        }
198        // Resume can invoked after changing the clock style.
199        View clockView = Utils.setClockStyle(getActivity(), mDigitalClock, mAnalogClock,
200                SettingsActivity.KEY_CLOCK_STYLE);
201        mClockStyle = (clockView == mDigitalClock ?
202                Utils.CLOCK_TYPE_DIGITAL : Utils.CLOCK_TYPE_ANALOG);
203        mAdapter.notifyDataSetChanged();
204
205        Utils.updateDate(mDateFormat, mDateFormatForAccessibility,mClockFrame);
206        Utils.refreshAlarm(getActivity(), mClockFrame);
207    }
208
209    @Override
210    public void onPause() {
211        super.onPause();
212        mPrefs.unregisterOnSharedPreferenceChangeListener(this);
213        Utils.cancelAlarmOnQuarterHour(getActivity(), mQuarterlyIntent);
214        getActivity().unregisterReceiver(mIntentReceiver);
215    }
216
217    @Override
218    public void onSaveInstanceState (Bundle outState) {
219        outState.putBoolean(BUTTONS_HIDDEN_KEY, mButtonsHidden);
220        super.onSaveInstanceState(outState);
221    }
222
223    @Override
224    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
225        if (key == SettingsActivity.KEY_CLOCK_STYLE) {
226            mClockStyle = prefs.getString(SettingsActivity.KEY_CLOCK_STYLE, mDefaultClockStyle);
227            mAdapter.notifyDataSetChanged();
228        }
229    }
230 }
231