blob: ebfe9a992644749326616c1b3782caa39c020eef [file] [log] [blame]
Daniel Sandlere3ea6e32009-11-11 22:06:33 -08001/*
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
17package com.android.internal.widget;
18
19import com.android.internal.R;
20
21import android.content.BroadcastReceiver;
22import android.content.Context;
23import android.content.Intent;
24import android.content.IntentFilter;
Jim Miller4e659132010-12-17 16:23:30 -080025import android.content.res.AssetManager;
Daniel Sandlere3ea6e32009-11-11 22:06:33 -080026import android.content.res.Resources;
27import android.database.ContentObserver;
28import android.graphics.Typeface;
29import android.os.Handler;
30import android.provider.Settings;
31import android.text.format.DateFormat;
32import android.util.AttributeSet;
33import android.view.View;
Daniel Sandler54df9de2010-03-17 21:52:24 -040034import android.widget.RelativeLayout;
Daniel Sandlere3ea6e32009-11-11 22:06:33 -080035import android.widget.TextView;
36
37import java.text.DateFormatSymbols;
38import java.util.Calendar;
39
40/**
41 * Displays the time
42 */
Daniel Sandler54df9de2010-03-17 21:52:24 -040043public class DigitalClock extends RelativeLayout {
Daniel Sandlere3ea6e32009-11-11 22:06:33 -080044
Jim Miller4e659132010-12-17 16:23:30 -080045 private static final String SYSTEM = "/system/fonts/";
46 private static final String SYSTEM_FONT_TIME_BACKGROUND = SYSTEM + "AndroidClock.ttf";
47 private static final String SYSTEM_FONT_TIME_FOREGROUND = SYSTEM + "AndroidClock_Highlight.ttf";
Daniel Sandlere3ea6e32009-11-11 22:06:33 -080048 private final static String M12 = "h:mm";
49 private final static String M24 = "kk:mm";
50
51 private Calendar mCalendar;
52 private String mFormat;
Jim Miller4e659132010-12-17 16:23:30 -080053 private TextView mTimeDisplayBackground;
54 private TextView mTimeDisplayForeground;
Daniel Sandlere3ea6e32009-11-11 22:06:33 -080055 private AmPm mAmPm;
56 private ContentObserver mFormatChangeObserver;
57 private boolean mLive = true;
58 private boolean mAttached;
59
60 /* called by system on minute ticks */
61 private final Handler mHandler = new Handler();
62 private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
63 @Override
64 public void onReceive(Context context, Intent intent) {
65 if (mLive && intent.getAction().equals(
66 Intent.ACTION_TIMEZONE_CHANGED)) {
67 mCalendar = Calendar.getInstance();
68 }
Daniel Sandlerf60e1082009-11-20 14:40:00 -050069 // Post a runnable to avoid blocking the broadcast.
70 mHandler.post(new Runnable() {
71 public void run() {
72 updateTime();
73 }
74 });
Daniel Sandlere3ea6e32009-11-11 22:06:33 -080075 }
76 };
77
78 static class AmPm {
79 private TextView mAmPm;
80 private String mAmString, mPmString;
81
82 AmPm(View parent, Typeface tf) {
83 mAmPm = (TextView) parent.findViewById(R.id.am_pm);
84 if (tf != null) {
85 mAmPm.setTypeface(tf);
86 }
87
88 String[] ampm = new DateFormatSymbols().getAmPmStrings();
89 mAmString = ampm[0];
90 mPmString = ampm[1];
91 }
92
93 void setShowAmPm(boolean show) {
94 mAmPm.setVisibility(show ? View.VISIBLE : View.GONE);
95 }
96
97 void setIsMorning(boolean isMorning) {
98 mAmPm.setText(isMorning ? mAmString : mPmString);
99 }
100 }
101
102 private class FormatChangeObserver extends ContentObserver {
103 public FormatChangeObserver() {
104 super(new Handler());
105 }
106 @Override
107 public void onChange(boolean selfChange) {
108 setDateFormat();
109 updateTime();
110 }
111 }
112
113 public DigitalClock(Context context) {
114 this(context, null);
115 }
116
117 public DigitalClock(Context context, AttributeSet attrs) {
118 super(context, attrs);
119 }
120
121 @Override
122 protected void onFinishInflate() {
123 super.onFinishInflate();
124
Jim Miller4e659132010-12-17 16:23:30 -0800125 AssetManager assets = mContext.getAssets();
126
127 /* The time display consists of two tones. That's why we have two overlapping text views. */
128 mTimeDisplayBackground = (TextView) findViewById(R.id.timeDisplayBackground);
129 mTimeDisplayBackground.setTypeface(Typeface.createFromFile(SYSTEM_FONT_TIME_BACKGROUND));
130 mTimeDisplayForeground = (TextView) findViewById(R.id.timeDisplayForeground);
131 mTimeDisplayForeground.setTypeface(Typeface.createFromFile(SYSTEM_FONT_TIME_FOREGROUND));
132 mAmPm = new AmPm(this, Typeface.createFromFile(SYSTEM_FONT_TIME_BACKGROUND));
Daniel Sandlere3ea6e32009-11-11 22:06:33 -0800133 mCalendar = Calendar.getInstance();
134
135 setDateFormat();
136 }
137
138 @Override
139 protected void onAttachedToWindow() {
140 super.onAttachedToWindow();
141
142 if (mAttached) return;
143 mAttached = true;
144
145 if (mLive) {
146 /* monitor time ticks, time changed, timezone */
147 IntentFilter filter = new IntentFilter();
148 filter.addAction(Intent.ACTION_TIME_TICK);
149 filter.addAction(Intent.ACTION_TIME_CHANGED);
150 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Daniel Sandlerf60e1082009-11-20 14:40:00 -0500151 mContext.registerReceiver(mIntentReceiver, filter);
Daniel Sandlere3ea6e32009-11-11 22:06:33 -0800152 }
153
154 /* monitor 12/24-hour display preference */
155 mFormatChangeObserver = new FormatChangeObserver();
156 mContext.getContentResolver().registerContentObserver(
157 Settings.System.CONTENT_URI, true, mFormatChangeObserver);
158
159 updateTime();
160 }
161
162 @Override
163 protected void onDetachedFromWindow() {
164 super.onDetachedFromWindow();
165
166 if (!mAttached) return;
167 mAttached = false;
168
169 if (mLive) {
170 mContext.unregisterReceiver(mIntentReceiver);
171 }
172 mContext.getContentResolver().unregisterContentObserver(
173 mFormatChangeObserver);
174 }
175
176
177 void updateTime(Calendar c) {
178 mCalendar = c;
179 updateTime();
180 }
181
182 private void updateTime() {
183 if (mLive) {
184 mCalendar.setTimeInMillis(System.currentTimeMillis());
185 }
186
187 CharSequence newTime = DateFormat.format(mFormat, mCalendar);
Jim Miller4e659132010-12-17 16:23:30 -0800188 mTimeDisplayBackground.setText(newTime);
189 mTimeDisplayForeground.setText(newTime);
Daniel Sandlere3ea6e32009-11-11 22:06:33 -0800190 mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
191 }
192
193 private void setDateFormat() {
Jim Miller4e659132010-12-17 16:23:30 -0800194 mFormat = android.text.format.DateFormat.is24HourFormat(getContext())
Daniel Sandlere3ea6e32009-11-11 22:06:33 -0800195 ? M24 : M12;
196 mAmPm.setShowAmPm(mFormat.equals(M12));
197 }
198
199 void setLive(boolean live) {
200 mLive = live;
201 }
202}