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