TextClock.java revision f7d5e0a53e168f2acc17b098bdd4b927fa1b1d6c
13d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy/* 23d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Copyright (C) 2012 The Android Open Source Project 33d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 43d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 53d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * you may not use this file except in compliance with the License. 63d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * You may obtain a copy of the License at 73d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 83d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 93d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Unless required by applicable law or agreed to in writing, software 113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * See the License for the specific language governing permissions and 143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * limitations under the License. 153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guypackage android.widget; 183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.BroadcastReceiver; 203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.ContentResolver; 213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.Context; 223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.Intent; 233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.IntentFilter; 243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.res.TypedArray; 253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.database.ContentObserver; 263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.net.Uri; 273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.os.Handler; 283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.os.SystemClock; 293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.provider.Settings; 303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.text.format.DateFormat; 313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.util.AttributeSet; 32a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guyimport android.view.RemotableViewMethod; 333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport com.android.internal.R; 353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport java.util.Calendar; 373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport java.util.TimeZone; 383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 39cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughesimport libcore.icu.LocaleData; 40cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes 413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport static android.view.ViewDebug.ExportedProperty; 423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport static android.widget.RemoteViews.*; 433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy/** 453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p><code>TextClock</code> can display the current date and/or time as 463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * a formatted string.</p> 47cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>This view honors the 24-hour format system setting. As such, it is 493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * possible and recommended to provide two different formatting patterns: 503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * one to display the date/time in 24-hour mode and one to display the 51cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * date/time in 12-hour mode. Most callers will want to use the defaults, 52cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * though, which will be appropriate for the user's locale.</p> 53cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>It is possible to determine whether the system is currently in 553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 24-hour mode by calling {@link #is24HourModeEnabled()}.</p> 56cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>The rules used by this widget to decide how to format the date and 583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * time are the following:</p> 593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>In 24-hour mode: 613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Use the value returned by {@link #getFormat24Hour()} when non-null</li> 633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use the value returned by {@link #getFormat12Hour()} when non-null</li> 64cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * <li>Otherwise, use a default value appropriate for the user's locale, such as {@code h:mm a}</li> 653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </li> 673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>In 12-hour mode: 683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Use the value returned by {@link #getFormat12Hour()} when non-null</li> 703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use the value returned by {@link #getFormat24Hour()} when non-null</li> 71cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * <li>Otherwise, use a default value appropriate for the user's locale, such as {@code HH:mm}</li> 723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </li> 743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 75cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>The {@link CharSequence} instances used as formatting patterns when calling either 773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link #setFormat24Hour(CharSequence)} or {@link #setFormat12Hour(CharSequence)} can 78cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * contain styling information. To do so, use a {@link android.text.Spanned} object. 79cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * Note that if you customize these strings, it is your responsibility to supply strings 80cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * appropriate for formatting dates and/or times in the user's locale.</p> 81cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format12Hour 833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format24Hour 843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_timeZone 853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy@RemoteView 873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guypublic class TextClock extends TextView { 883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 89cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * The default formatting pattern in 12-hour mode. This pattern is used 903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * if {@link #setFormat12Hour(CharSequence)} is called with a null pattern 913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or if no pattern was specified when creating an instance of this class. 92cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This default pattern shows only the time, hours and minutes, and an am/pm 943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * indicator. 953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat12Hour(CharSequence) 973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat12Hour() 9809b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 99cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @deprecated Let the system use locale-appropriate defaults instead. 1003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 101cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm a"; 1023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 104cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * The default formatting pattern in 24-hour mode. This pattern is used 1053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * if {@link #setFormat24Hour(CharSequence)} is called with a null pattern 1063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or if no pattern was specified when creating an instance of this class. 1073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This default pattern shows only the time, hours and minutes. 109cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 110cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #setFormat24Hour(CharSequence) 111cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #getFormat24Hour() 11209b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 113cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @deprecated Let the system use locale-appropriate defaults instead. 1143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 115cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes public static final CharSequence DEFAULT_FORMAT_24_HOUR = "H:mm"; 1163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 117cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes private CharSequence mFormat12; 118cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes private CharSequence mFormat24; 1193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 1213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private CharSequence mFormat; 1223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 1233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private boolean mHasSeconds; 1243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private boolean mAttached; 1263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private Calendar mTime; 1283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private String mTimeZone; 1293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final ContentObserver mFormatChangeObserver = new ContentObserver(new Handler()) { 1313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onChange(boolean selfChange) { 1333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 1343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onChange(boolean selfChange, Uri uri) { 1393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 1403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 1453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onReceive(Context context, Intent intent) { 147a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (mTimeZone == null && Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 148a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy final String timeZone = intent.getStringExtra("time-zone"); 149a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy createTime(timeZone); 1503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 151a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy onTimeChanged(); 1523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final Runnable mTicker = new Runnable() { 1563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void run() { 1573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy long now = SystemClock.uptimeMillis(); 1603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy long next = now + (1000 - now % 1000); 1613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getHandler().postAtTime(mTicker, next); 1633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 16709b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * Creates a new clock using the default patterns for the current locale. 168cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 1693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 1713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @SuppressWarnings("UnusedDeclaration") 1733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context) { 1743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super(context); 1753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy init(); 1763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 1793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Creates a new clock inflated from XML. This object's properties are 1803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * intialized from the attributes specified in XML. 181cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 1823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This constructor uses a default style of 0, so the only attribute values 1833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * applied are those in the Context's Theme and the given AttributeSet. 1843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 1873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param attrs The attributes of the XML tag that is inflating the view 1883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @SuppressWarnings("UnusedDeclaration") 1903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context, AttributeSet attrs) { 1913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy this(context, attrs, 0); 1923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 1953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Creates a new clock inflated from XML. This object's properties are 1963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * intialized from the attributes specified in XML. 1973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 2003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param attrs The attributes of the XML tag that is inflating the view 2013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param defStyle The default style to apply to this view. If 0, no style 2023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * will be applied (beyond what is included in the theme). This may 2033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * either be an attribute resource, whose value will be retrieved 2043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * from the current theme, or an explicit style resource 2053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 2063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context, AttributeSet attrs, int defStyle) { 2073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super(context, attrs, defStyle); 2083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextClock, defStyle, 0); 2103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy try { 211cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat12 = a.getText(R.styleable.TextClock_format12Hour); 212cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat24 = a.getText(R.styleable.TextClock_format24Hour); 2133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTimeZone = a.getString(R.styleable.TextClock_timeZone); 2143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } finally { 2153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy a.recycle(); 2163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy init(); 2193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void init() { 222cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes if (mFormat12 == null || mFormat24 == null) { 223cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); 224cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes if (mFormat12 == null) { 225f7d5e0a53e168f2acc17b098bdd4b927fa1b1d6cElliott Hughes mFormat12 = ld.timeFormat_hm; 226cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes } 227cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes if (mFormat24 == null) { 228f7d5e0a53e168f2acc17b098bdd4b927fa1b1d6cElliott Hughes mFormat24 = ld.timeFormat_Hm; 229cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes } 230cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes } 231cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes 2323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(mTimeZone); 2333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy // Wait until onAttachedToWindow() to handle the ticker 2343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(false); 2353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void createTime(String timeZone) { 2383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (timeZone != null) { 2393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime = Calendar.getInstance(TimeZone.getTimeZone(timeZone)); 2403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 2413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime = Calendar.getInstance(); 2423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 2463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns the formatting pattern used to display the date and/or time 2473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 12-hour mode. The formatting pattern syntax is described in 2483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 249cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 2503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return A {@link CharSequence} or null. 251cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 252cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #setFormat12Hour(CharSequence) 253cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #is24HourModeEnabled() 2543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 2553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 2563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public CharSequence getFormat12Hour() { 2573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mFormat12; 2583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 26109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>Specifies the formatting pattern used to display the date and/or time 2623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 12-hour mode. The formatting pattern syntax is described in 26309b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat}.</p> 2643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 26509b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used 2663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns 26709b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * are set to null, the default pattern for the current locale will be used 26809b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * instead.</p> 26909b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 27009b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p><strong>Note:</strong> if styling is not needed, it is highly recommended 27109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * you supply a format string generated by 27209b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method 27309b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * takes care of generating a format string adapted to the desired locale.</p> 27409b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 2753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param format A date/time formatting pattern as described in {@link DateFormat} 277cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 2783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat12Hour() 2793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 28009b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * @see DateFormat#getBestDateTimePattern(java.util.Locale, String) 2813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see DateFormat 282cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 2833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format12Hour 2843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 285a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 2863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setFormat12Hour(CharSequence format) { 2873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat12 = format; 2883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 2903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 2913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 2943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns the formatting pattern used to display the date and/or time 2953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 24-hour mode. The formatting pattern syntax is described in 2963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 2973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return A {@link CharSequence} or null. 2993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat24Hour(CharSequence) 3013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 3023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 3043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public CharSequence getFormat24Hour() { 3053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mFormat24; 3063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 30909b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>Specifies the formatting pattern used to display the date and/or time 3103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 24-hour mode. The formatting pattern syntax is described in 31109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat}.</p> 31209b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 31309b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used 31409b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns 31509b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * are set to null, the default pattern for the current locale will be used 31609b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * instead.</p> 317cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 31809b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p><strong>Note:</strong> if styling is not needed, it is highly recommended 31909b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * you supply a format string generated by 32009b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method 32109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * takes care of generating a format string adapted to the desired locale.</p> 3223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param format A date/time formatting pattern as described in {@link DateFormat} 3243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat24Hour() 326cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #is24HourModeEnabled() 32709b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * @see DateFormat#getBestDateTimePattern(java.util.Locale, String) 3283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see DateFormat 3293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format24Hour 3313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 332a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 3333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setFormat24Hour(CharSequence format) { 3343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat24 = format; 3353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 3373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 3383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Indicates whether the system is currently using the 24-hour mode. 342cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * When the system is in 24-hour mode, this view will use the pattern 3443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * returned by {@link #getFormat24Hour()}. In 12-hour mode, the pattern 3453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * returned by {@link #getFormat12Hour()} is used instead. 346cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * If either one of the formats is null, the other format is used. If 34809b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * both formats are null, the default formats for the current locale are used. 349cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return true if time should be displayed in 24-hour format, false if it 3513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * should be displayed in 12-hour format. 352cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat12Hour(CharSequence) 354cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #getFormat12Hour() 3553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat24Hour(CharSequence) 356cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #getFormat24Hour() 3573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public boolean is24HourModeEnabled() { 3593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return DateFormat.is24HourFormat(getContext()); 3603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Indicates which time zone is currently used by this view. 364cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return The ID of the current time zone or null if the default time zone, 3663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * as set by the user, must be used 3673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see TimeZone 3693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see java.util.TimeZone#getAvailableIDs() 370cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #setTimeZone(String) 3713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public String getTimeZone() { 3733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mTimeZone; 3743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Sets the specified time zone to use in this clock. When the time zone 3783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * is set through this method, system time zone changes (when the user 3793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * sets the time zone in settings for instance) will be ignored. 3803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param timeZone The desired time zone's ID as specified in {@link TimeZone} 3823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or null to user the time zone specified by the user 3833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * (system time zone) 3843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getTimeZone() 3863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see java.util.TimeZone#getAvailableIDs() 3873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see TimeZone#getTimeZone(String) 3883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_timeZone 3903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 391a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 3923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setTimeZone(String timeZone) { 3933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTimeZone = timeZone; 3943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(timeZone); 3963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 3973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 4003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()} 4013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * depending on whether the user has selected 24-hour format. 402cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 4033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Calling this method does not schedule or unschedule the time ticker. 4043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void chooseFormat() { 4063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(true); 4073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 41006c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * Returns the current format string. Always valid after constructor has 41106c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * finished, and will never be {@code null}. 41206c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * 41306c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * @hide 41406c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey */ 41506c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey public CharSequence getFormat() { 41606c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey return mFormat; 41706c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey } 41806c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey 41906c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey /** 4203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()} 4213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * depending on whether the user has selected 24-hour format. 422cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 4233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param handleTicker true if calling this method should schedule/unschedule the 4243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * time ticker, false otherwise 4253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void chooseFormat(boolean handleTicker) { 4273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final boolean format24Requested = is24HourModeEnabled(); 4283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 429cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); 430cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes 4313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (format24Requested) { 432f7d5e0a53e168f2acc17b098bdd4b927fa1b1d6cElliott Hughes mFormat = abc(mFormat24, mFormat12, ld.timeFormat_Hm); 4333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 434f7d5e0a53e168f2acc17b098bdd4b927fa1b1d6cElliott Hughes mFormat = abc(mFormat12, mFormat24, ld.timeFormat_hm); 4353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy boolean hadSeconds = mHasSeconds; 4383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mHasSeconds = DateFormat.hasSeconds(mFormat); 4393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 440a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (handleTicker && mAttached && hadSeconds != mHasSeconds) { 441a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (hadSeconds) getHandler().removeCallbacks(mTicker); 442a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy else mTicker.run(); 4433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 4473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns a if not null, else return b if not null, else return c. 4483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private static CharSequence abc(CharSequence a, CharSequence b, CharSequence c) { 4503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return a == null ? (b == null ? c : b) : a; 4513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 4543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy protected void onAttachedToWindow() { 4553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super.onAttachedToWindow(); 4563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (!mAttached) { 4583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mAttached = true; 4593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy registerReceiver(); 4613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy registerObserver(); 4623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(mTimeZone); 4643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (mHasSeconds) { 4663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTicker.run(); 4673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 4683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 4693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 4743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy protected void onDetachedFromWindow() { 4753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super.onDetachedFromWindow(); 4763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (mAttached) { 4783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy unregisterReceiver(); 4793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy unregisterObserver(); 4803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getHandler().removeCallbacks(mTicker); 4823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mAttached = false; 4843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void registerReceiver() { 4883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final IntentFilter filter = new IntentFilter(); 4893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIME_TICK); 4913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIME_CHANGED); 4923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 4933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getContext().registerReceiver(mIntentReceiver, filter, null, getHandler()); 4953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void registerObserver() { 4983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final ContentResolver resolver = getContext().getContentResolver(); 4993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy resolver.registerContentObserver(Settings.System.CONTENT_URI, true, mFormatChangeObserver); 5003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void unregisterReceiver() { 5033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getContext().unregisterReceiver(mIntentReceiver); 5043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void unregisterObserver() { 5073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final ContentResolver resolver = getContext().getContentResolver(); 5083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy resolver.unregisterContentObserver(mFormatChangeObserver); 5093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void onTimeChanged() { 5123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime.setTimeInMillis(System.currentTimeMillis()); 5133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy setText(DateFormat.format(mFormat, mTime)); 5143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy} 516