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