1 // Copyright 2013 Google Inc. All Rights Reserved. 2 3 package com.android.deskclock.widget; 4 5 import android.content.ContentResolver; 6 import android.content.Context; 7 import android.content.res.TypedArray; 8 import android.database.ContentObserver; 9 import android.net.Uri; 10 import android.os.Handler; 11 import android.provider.Settings; 12 import android.text.format.DateFormat; 13 import android.util.AttributeSet; 14 import android.widget.TextView; 15 16 import com.android.deskclock.R; 17 import com.android.deskclock.Utils; 18 19 import java.util.Calendar; 20 21 /** 22 * Based on {@link android.widget.TextClock}, This widget displays a constant time of day using 23 * format specifiers. {@link android.widget.TextClock} Doesn't support a non ticking clock. 24 */ 25 public class TextTime extends TextView { 26 public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm a"; 27 28 public static final CharSequence DEFAULT_FORMAT_24_HOUR = "H:mm"; 29 30 private CharSequence mFormat12; 31 private CharSequence mFormat24; 32 private CharSequence mFormat; 33 private String mContentDescriptionFormat; 34 35 private boolean mAttached; 36 37 private int mHour; 38 private int mMinute; 39 40 private final ContentObserver mFormatChangeObserver = new ContentObserver(new Handler()) { 41 @Override 42 public void onChange(boolean selfChange) { 43 chooseFormat(); 44 updateTime(); 45 } 46 47 @Override 48 public void onChange(boolean selfChange, Uri uri) { 49 chooseFormat(); 50 updateTime(); 51 } 52 }; 53 54 @SuppressWarnings("UnusedDeclaration") TextTime(Context context)55 public TextTime(Context context) { 56 this(context, null); 57 } 58 59 @SuppressWarnings("UnusedDeclaration") TextTime(Context context, AttributeSet attrs)60 public TextTime(Context context, AttributeSet attrs) { 61 this(context, attrs, 0); 62 } 63 TextTime(Context context, AttributeSet attrs, int defStyle)64 public TextTime(Context context, AttributeSet attrs, int defStyle) { 65 super(context, attrs, defStyle); 66 67 final TypedArray styledAttributes = context.obtainStyledAttributes( 68 attrs, R.styleable.TextTime, defStyle, 0); 69 try { 70 mFormat12 = styledAttributes.getText(R.styleable.TextTime_format12Hour); 71 mFormat24 = styledAttributes.getText(R.styleable.TextTime_format24Hour); 72 } finally { 73 styledAttributes.recycle(); 74 } 75 chooseFormat(); 76 } 77 78 @SuppressWarnings("UnusedDeclaration") getFormat12Hour()79 public CharSequence getFormat12Hour() { 80 return mFormat12; 81 } 82 83 @SuppressWarnings("UnusedDeclaration") setFormat12Hour(CharSequence format)84 public void setFormat12Hour(CharSequence format) { 85 mFormat12 = format; 86 87 chooseFormat(); 88 updateTime(); 89 } 90 91 @SuppressWarnings("UnusedDeclaration") getFormat24Hour()92 public CharSequence getFormat24Hour() { 93 return mFormat24; 94 } 95 96 @SuppressWarnings("UnusedDeclaration") setFormat24Hour(CharSequence format)97 public void setFormat24Hour(CharSequence format) { 98 mFormat24 = format; 99 100 chooseFormat(); 101 updateTime(); 102 } 103 chooseFormat()104 private void chooseFormat() { 105 final boolean format24Requested = DateFormat.is24HourFormat(getContext()); 106 if (format24Requested) { 107 mFormat = mFormat24 == null ? DEFAULT_FORMAT_24_HOUR : mFormat24; 108 } else { 109 mFormat = mFormat12 == null ? DEFAULT_FORMAT_12_HOUR : mFormat12; 110 } 111 mContentDescriptionFormat = mFormat.toString(); 112 } 113 114 @Override onAttachedToWindow()115 protected void onAttachedToWindow() { 116 super.onAttachedToWindow(); 117 if (!mAttached) { 118 mAttached = true; 119 registerObserver(); 120 updateTime(); 121 } 122 } 123 124 @Override onDetachedFromWindow()125 protected void onDetachedFromWindow() { 126 super.onDetachedFromWindow(); 127 if (mAttached) { 128 unregisterObserver(); 129 mAttached = false; 130 } 131 } 132 registerObserver()133 private void registerObserver() { 134 final ContentResolver resolver = getContext().getContentResolver(); 135 resolver.registerContentObserver(Settings.System.CONTENT_URI, true, mFormatChangeObserver); 136 } 137 unregisterObserver()138 private void unregisterObserver() { 139 final ContentResolver resolver = getContext().getContentResolver(); 140 resolver.unregisterContentObserver(mFormatChangeObserver); 141 } 142 setFormat(Context context)143 public void setFormat(Context context) { 144 setFormat12Hour(Utils.get12ModeFormat(context, true /* showAmPm */)); 145 setFormat24Hour(Utils.get24ModeFormat()); 146 } 147 setTime(int hour, int minute)148 public void setTime(int hour, int minute) { 149 mHour = hour; 150 mMinute = minute; 151 updateTime(); 152 } 153 updateTime()154 private void updateTime() { 155 final Calendar calendar = Calendar.getInstance(); 156 calendar.set(Calendar.HOUR_OF_DAY, mHour); 157 calendar.set(Calendar.MINUTE, mMinute); 158 setText(DateFormat.format(mFormat, calendar)); 159 if (mContentDescriptionFormat != null) { 160 setContentDescription(DateFormat.format(mContentDescriptionFormat, calendar)); 161 } else { 162 setContentDescription(DateFormat.format(mFormat, calendar)); 163 } 164 } 165 } 166