• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 
17 package com.android.deskclock;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.res.Resources;
24 import android.database.ContentObserver;
25 import android.graphics.Typeface;
26 import android.os.Handler;
27 import android.provider.Settings;
28 import android.text.format.DateFormat;
29 import android.util.AttributeSet;
30 import android.view.View;
31 import android.widget.LinearLayout;
32 import android.widget.TextView;
33 
34 import java.text.DateFormatSymbols;
35 import java.util.Calendar;
36 
37 /**
38  * Displays the time
39  */
40 public class DigitalClock extends LinearLayout {
41 
42     private final static String M12 = "h:mm";
43 
44     private Calendar mCalendar;
45     private String mFormat;
46     private TextView mTimeDisplay;
47     private AmPm mAmPm;
48     private ContentObserver mFormatChangeObserver;
49     private boolean mLive = true;
50     private boolean mAttached;
51 
52     /* called by system on minute ticks */
53     private final Handler mHandler = new Handler();
54     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
55             @Override
56             public void onReceive(Context context, Intent intent) {
57                 if (mLive && intent.getAction().equals(
58                             Intent.ACTION_TIMEZONE_CHANGED)) {
59                     mCalendar = Calendar.getInstance();
60                 }
61                 // Post a runnable to avoid blocking the broadcast.
62                 mHandler.post(new Runnable() {
63                         public void run() {
64                             updateTime();
65                         }
66                 });
67             }
68         };
69 
70     private static Typeface sTypeface;
71 
72     static class AmPm {
73         private TextView mAmPm;
74         private String mAmString, mPmString;
75 
AmPm(View parent)76         AmPm(View parent) {
77             mAmPm = (TextView) parent.findViewById(R.id.am_pm);
78 
79             String[] ampm = new DateFormatSymbols().getAmPmStrings();
80             mAmString = ampm[0];
81             mPmString = ampm[1];
82         }
83 
setShowAmPm(boolean show)84         void setShowAmPm(boolean show) {
85             mAmPm.setVisibility(show ? View.VISIBLE : View.GONE);
86         }
87 
setIsMorning(boolean isMorning)88         void setIsMorning(boolean isMorning) {
89             mAmPm.setText(isMorning ? mAmString : mPmString);
90         }
91     }
92 
93     private class FormatChangeObserver extends ContentObserver {
FormatChangeObserver()94         public FormatChangeObserver() {
95             super(new Handler());
96         }
97         @Override
onChange(boolean selfChange)98         public void onChange(boolean selfChange) {
99             setDateFormat();
100             updateTime();
101         }
102     }
103 
DigitalClock(Context context)104     public DigitalClock(Context context) {
105         this(context, null);
106     }
107 
DigitalClock(Context context, AttributeSet attrs)108     public DigitalClock(Context context, AttributeSet attrs) {
109         super(context, attrs);
110     }
111 
112     @Override
onFinishInflate()113     protected void onFinishInflate() {
114         super.onFinishInflate();
115 
116         if (sTypeface == null) {
117             sTypeface = Typeface.createFromAsset(getContext().getAssets(),
118                 "fonts/Clockopia.ttf");
119         }
120         mTimeDisplay = (TextView) findViewById(R.id.timeDisplay);
121         mTimeDisplay.setTypeface(sTypeface);
122         mAmPm = new AmPm(this);
123         mCalendar = Calendar.getInstance();
124 
125         setDateFormat();
126     }
127 
128     @Override
onAttachedToWindow()129     protected void onAttachedToWindow() {
130         super.onAttachedToWindow();
131 
132         if (Log.LOGV) Log.v("onAttachedToWindow " + this);
133 
134         if (mAttached) return;
135         mAttached = true;
136 
137         if (mLive) {
138             /* monitor time ticks, time changed, timezone */
139             IntentFilter filter = new IntentFilter();
140             filter.addAction(Intent.ACTION_TIME_TICK);
141             filter.addAction(Intent.ACTION_TIME_CHANGED);
142             filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
143             getContext().registerReceiver(mIntentReceiver, filter);
144         }
145 
146         /* monitor 12/24-hour display preference */
147         mFormatChangeObserver = new FormatChangeObserver();
148         getContext().getContentResolver().registerContentObserver(
149                 Settings.System.CONTENT_URI, true, mFormatChangeObserver);
150 
151         updateTime();
152     }
153 
154     @Override
onDetachedFromWindow()155     protected void onDetachedFromWindow() {
156         super.onDetachedFromWindow();
157 
158         if (!mAttached) return;
159         mAttached = false;
160 
161         if (mLive) {
162             getContext().unregisterReceiver(mIntentReceiver);
163         }
164         getContext().getContentResolver().unregisterContentObserver(
165                 mFormatChangeObserver);
166     }
167 
168 
updateTime(Calendar c)169     void updateTime(Calendar c) {
170         mCalendar = c;
171         updateTime();
172     }
173 
updateTime()174     private void updateTime() {
175         if (mLive) {
176             mCalendar.setTimeInMillis(System.currentTimeMillis());
177         }
178 
179         CharSequence newTime = DateFormat.format(mFormat, mCalendar);
180         mTimeDisplay.setText(newTime);
181         mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
182     }
183 
setDateFormat()184     private void setDateFormat() {
185         mFormat = Alarms.get24HourMode(getContext()) ? Alarms.M24 : M12;
186         mAmPm.setShowAmPm(mFormat == M12);
187     }
188 
setLive(boolean live)189     void setLive(boolean live) {
190         mLive = live;
191     }
192 
setTypeface(Typeface tf)193     void setTypeface(Typeface tf) {
194         mTimeDisplay.setTypeface(tf);
195     }
196 }
197