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 199c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinekimport android.app.ActivityManager; 203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.BroadcastReceiver; 213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.ContentResolver; 223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.Context; 233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.Intent; 243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.IntentFilter; 253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.content.res.TypedArray; 263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.database.ContentObserver; 273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.net.Uri; 283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.os.Handler; 293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.os.SystemClock; 309c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinekimport android.os.UserHandle; 313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.provider.Settings; 323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.text.format.DateFormat; 333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport android.util.AttributeSet; 34a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guyimport android.view.RemotableViewMethod; 353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport com.android.internal.R; 373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport java.util.Calendar; 393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport java.util.TimeZone; 403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 41cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughesimport libcore.icu.LocaleData; 42cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes 433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport static android.view.ViewDebug.ExportedProperty; 443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport static android.widget.RemoteViews.*; 453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy/** 473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p><code>TextClock</code> can display the current date and/or time as 483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * a formatted string.</p> 49cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>This view honors the 24-hour format system setting. As such, it is 513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * possible and recommended to provide two different formatting patterns: 523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * one to display the date/time in 24-hour mode and one to display the 53cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * date/time in 12-hour mode. Most callers will want to use the defaults, 54cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * though, which will be appropriate for the user's locale.</p> 55cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>It is possible to determine whether the system is currently in 573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 24-hour mode by calling {@link #is24HourModeEnabled()}.</p> 58cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>The rules used by this widget to decide how to format the date and 603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * time are the following:</p> 613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>In 24-hour mode: 633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Use the value returned by {@link #getFormat24Hour()} when non-null</li> 653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use the value returned by {@link #getFormat12Hour()} when non-null</li> 66cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * <li>Otherwise, use a default value appropriate for the user's locale, such as {@code h:mm a}</li> 673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </li> 693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>In 12-hour mode: 703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Use the value returned by {@link #getFormat12Hour()} when non-null</li> 723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use the value returned by {@link #getFormat24Hour()} when non-null</li> 73cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * <li>Otherwise, use a default value appropriate for the user's locale, such as {@code HH:mm}</li> 743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </li> 763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 77cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>The {@link CharSequence} instances used as formatting patterns when calling either 793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link #setFormat24Hour(CharSequence)} or {@link #setFormat12Hour(CharSequence)} can 80cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * contain styling information. To do so, use a {@link android.text.Spanned} object. 81cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * Note that if you customize these strings, it is your responsibility to supply strings 82cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * appropriate for formatting dates and/or times in the user's locale.</p> 83cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format12Hour 853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format24Hour 863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_timeZone 873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy@RemoteView 893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guypublic class TextClock extends TextView { 903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 91cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * The default formatting pattern in 12-hour mode. This pattern is used 923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * if {@link #setFormat12Hour(CharSequence)} is called with a null pattern 933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or if no pattern was specified when creating an instance of this class. 94cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This default pattern shows only the time, hours and minutes, and an am/pm 963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * indicator. 973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat12Hour(CharSequence) 993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat12Hour() 10009b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 101cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @deprecated Let the system use locale-appropriate defaults instead. 1023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 103cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm a"; 1043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 106cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * The default formatting pattern in 24-hour mode. This pattern is used 1073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * if {@link #setFormat24Hour(CharSequence)} is called with a null pattern 1083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or if no pattern was specified when creating an instance of this class. 1093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This default pattern shows only the time, hours and minutes. 111cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 112cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #setFormat24Hour(CharSequence) 113cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #getFormat24Hour() 11409b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 115cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @deprecated Let the system use locale-appropriate defaults instead. 1163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 117cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes public static final CharSequence DEFAULT_FORMAT_24_HOUR = "H:mm"; 1183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 119cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes private CharSequence mFormat12; 120cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes private CharSequence mFormat24; 1213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 1233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private CharSequence mFormat; 1243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 1253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private boolean mHasSeconds; 1263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private boolean mAttached; 1283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private Calendar mTime; 1303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private String mTimeZone; 1313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1329c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek private boolean mShowCurrentUserTime; 1339c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek 1343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final ContentObserver mFormatChangeObserver = new ContentObserver(new Handler()) { 1353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onChange(boolean selfChange) { 1373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 1383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onChange(boolean selfChange, Uri uri) { 1433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 1443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 1493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onReceive(Context context, Intent intent) { 151a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (mTimeZone == null && Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 152a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy final String timeZone = intent.getStringExtra("time-zone"); 153a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy createTime(timeZone); 1543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 155a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy onTimeChanged(); 1563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final Runnable mTicker = new Runnable() { 1603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void run() { 1613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy long now = SystemClock.uptimeMillis(); 1643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy long next = now + (1000 - now % 1000); 1653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getHandler().postAtTime(mTicker, next); 1673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 17109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * Creates a new clock using the default patterns for the current locale. 172cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 1733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 1753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @SuppressWarnings("UnusedDeclaration") 1773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context) { 1783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super(context); 1793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy init(); 1803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 1833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Creates a new clock inflated from XML. This object's properties are 1843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * intialized from the attributes specified in XML. 185cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 1863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This constructor uses a default style of 0, so the only attribute values 1873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * applied are those in the Context's Theme and the given AttributeSet. 1883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 1913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param attrs The attributes of the XML tag that is inflating the view 1923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @SuppressWarnings("UnusedDeclaration") 1943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context, AttributeSet attrs) { 1953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy this(context, attrs, 0); 1963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 1993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Creates a new clock inflated from XML. This object's properties are 2003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * intialized from the attributes specified in XML. 2013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 2033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 2043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param attrs The attributes of the XML tag that is inflating the view 205617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleAttr An attribute in the current theme that contains a 206617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * reference to a style resource that supplies default values for 207617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * the view. Can be 0 to not look for defaults. 2083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 209617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public TextClock(Context context, AttributeSet attrs, int defStyleAttr) { 210617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 211617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 212617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 213617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public TextClock(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 214617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 2153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 216617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 217617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette attrs, R.styleable.TextClock, defStyleAttr, defStyleRes); 2183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy try { 219cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat12 = a.getText(R.styleable.TextClock_format12Hour); 220cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat24 = a.getText(R.styleable.TextClock_format24Hour); 2213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTimeZone = a.getString(R.styleable.TextClock_timeZone); 2223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } finally { 2233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy a.recycle(); 2243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy init(); 2273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void init() { 230cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes if (mFormat12 == null || mFormat24 == null) { 231cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); 232cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes if (mFormat12 == null) { 233cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat12 = ld.timeFormat12; 234cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes } 235cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes if (mFormat24 == null) { 236cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat24 = ld.timeFormat24; 237cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes } 238cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes } 239cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes 2403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(mTimeZone); 2413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy // Wait until onAttachedToWindow() to handle the ticker 2423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(false); 2433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void createTime(String timeZone) { 2463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (timeZone != null) { 2473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime = Calendar.getInstance(TimeZone.getTimeZone(timeZone)); 2483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 2493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime = Calendar.getInstance(); 2503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 2543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns the formatting pattern used to display the date and/or time 2553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 12-hour mode. The formatting pattern syntax is described in 2563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 257cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 2583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return A {@link CharSequence} or null. 259cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 260cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #setFormat12Hour(CharSequence) 261cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #is24HourModeEnabled() 2623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 2633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 2643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public CharSequence getFormat12Hour() { 2653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mFormat12; 2663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 26909b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>Specifies the formatting pattern used to display the date and/or time 2703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 12-hour mode. The formatting pattern syntax is described in 27109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat}.</p> 2723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 27309b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used 2743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns 27509b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * are set to null, the default pattern for the current locale will be used 27609b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * instead.</p> 27709b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 27809b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p><strong>Note:</strong> if styling is not needed, it is highly recommended 27909b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * you supply a format string generated by 28009b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method 28109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * takes care of generating a format string adapted to the desired locale.</p> 28209b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 2833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param format A date/time formatting pattern as described in {@link DateFormat} 285cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 2863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat12Hour() 2873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 28809b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * @see DateFormat#getBestDateTimePattern(java.util.Locale, String) 2893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see DateFormat 290cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 2913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format12Hour 2923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 293a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 2943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setFormat12Hour(CharSequence format) { 2953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat12 = format; 2963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 2983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 2993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns the formatting pattern used to display the date and/or time 3033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 24-hour mode. The formatting pattern syntax is described in 3043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 3053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return A {@link CharSequence} or null. 3073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat24Hour(CharSequence) 3093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 3103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 3123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public CharSequence getFormat24Hour() { 3133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mFormat24; 3143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 31709b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>Specifies the formatting pattern used to display the date and/or time 3183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 24-hour mode. The formatting pattern syntax is described in 31909b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat}.</p> 32009b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * 32109b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used 32209b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns 32309b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * are set to null, the default pattern for the current locale will be used 32409b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * instead.</p> 325cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 32609b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * <p><strong>Note:</strong> if styling is not needed, it is highly recommended 32709b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * you supply a format string generated by 32809b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method 32909b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * takes care of generating a format string adapted to the desired locale.</p> 3303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param format A date/time formatting pattern as described in {@link DateFormat} 3323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat24Hour() 334cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #is24HourModeEnabled() 33509b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * @see DateFormat#getBestDateTimePattern(java.util.Locale, String) 3363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see DateFormat 3373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format24Hour 3393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 340a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 3413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setFormat24Hour(CharSequence format) { 3423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat24 = format; 3433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 3453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 3463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3499c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek * Sets whether this clock should always track the current user and not the user of the 3509c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek * current process. This is used for single instance processes like the systemUI who need 3519c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek * to display time for different users. 3529c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek * 3539c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek * @hide 3549c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek */ 3559c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek public void setShowCurrentUserTime(boolean showCurrentUserTime) { 3569c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek mShowCurrentUserTime = showCurrentUserTime; 3579c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek 3589c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek chooseFormat(); 3599c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek onTimeChanged(); 3609c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek unregisterObserver(); 3619c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek registerObserver(); 3629c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek } 3639c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek 3649c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek /** 3653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Indicates whether the system is currently using the 24-hour mode. 366cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * When the system is in 24-hour mode, this view will use the pattern 3683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * returned by {@link #getFormat24Hour()}. In 12-hour mode, the pattern 3693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * returned by {@link #getFormat12Hour()} is used instead. 370cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * If either one of the formats is null, the other format is used. If 37209b1994c4d3c47bfa41374a4d420eb5110b9a48aRomain Guy * both formats are null, the default formats for the current locale are used. 373cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return true if time should be displayed in 24-hour format, false if it 3753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * should be displayed in 12-hour format. 376cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat12Hour(CharSequence) 378cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #getFormat12Hour() 3793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat24Hour(CharSequence) 380cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #getFormat24Hour() 3813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public boolean is24HourModeEnabled() { 3839c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek if (mShowCurrentUserTime) { 3849c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek return DateFormat.is24HourFormat(getContext(), ActivityManager.getCurrentUser()); 3859c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek } else { 3869c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek return DateFormat.is24HourFormat(getContext()); 3879c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek } 3883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Indicates which time zone is currently used by this view. 392cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 3933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return The ID of the current time zone or null if the default time zone, 3943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * as set by the user, must be used 3953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see TimeZone 3973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see java.util.TimeZone#getAvailableIDs() 398cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * @see #setTimeZone(String) 3993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public String getTimeZone() { 4013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mTimeZone; 4023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 4053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Sets the specified time zone to use in this clock. When the time zone 4063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * is set through this method, system time zone changes (when the user 4073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * sets the time zone in settings for instance) will be ignored. 4083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 4093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param timeZone The desired time zone's ID as specified in {@link TimeZone} 4103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or null to user the time zone specified by the user 4113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * (system time zone) 4123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 4133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getTimeZone() 4143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see java.util.TimeZone#getAvailableIDs() 4153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see TimeZone#getTimeZone(String) 4163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 4173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_timeZone 4183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 419a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 4203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setTimeZone(String timeZone) { 4213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTimeZone = timeZone; 4223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(timeZone); 4243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 4253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 4283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()} 4293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * depending on whether the user has selected 24-hour format. 430cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 4313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Calling this method does not schedule or unschedule the time ticker. 4323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void chooseFormat() { 4343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(true); 4353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 43806c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * Returns the current format string. Always valid after constructor has 43906c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * finished, and will never be {@code null}. 44006c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * 44106c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey * @hide 44206c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey */ 44306c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey public CharSequence getFormat() { 44406c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey return mFormat; 44506c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey } 44606c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey 44706c5f8a768bcd4f7b6441f7525bd5c639399fc76Jeff Sharkey /** 4483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()} 4493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * depending on whether the user has selected 24-hour format. 450cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes * 4513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param handleTicker true if calling this method should schedule/unschedule the 4523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * time ticker, false otherwise 4533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void chooseFormat(boolean handleTicker) { 4553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final boolean format24Requested = is24HourModeEnabled(); 4563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 457cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); 458cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes 4593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (format24Requested) { 460cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat = abc(mFormat24, mFormat12, ld.timeFormat24); 4613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 462cdafd37f3148dfc6f44f2e5de8b31adb6bf9e476Elliott Hughes mFormat = abc(mFormat12, mFormat24, ld.timeFormat12); 4633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy boolean hadSeconds = mHasSeconds; 4663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mHasSeconds = DateFormat.hasSeconds(mFormat); 4673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 468a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (handleTicker && mAttached && hadSeconds != mHasSeconds) { 469a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (hadSeconds) getHandler().removeCallbacks(mTicker); 470a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy else mTicker.run(); 4713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 4753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns a if not null, else return b if not null, else return c. 4763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private static CharSequence abc(CharSequence a, CharSequence b, CharSequence c) { 4783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return a == null ? (b == null ? c : b) : a; 4793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 4823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy protected void onAttachedToWindow() { 4833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super.onAttachedToWindow(); 4843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (!mAttached) { 4863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mAttached = true; 4873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy registerReceiver(); 4893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy registerObserver(); 4903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(mTimeZone); 4923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (mHasSeconds) { 4943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTicker.run(); 4953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 4963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 4973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 5023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy protected void onDetachedFromWindow() { 5033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super.onDetachedFromWindow(); 5043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (mAttached) { 5063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy unregisterReceiver(); 5073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy unregisterObserver(); 5083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getHandler().removeCallbacks(mTicker); 5103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mAttached = false; 5123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void registerReceiver() { 5163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final IntentFilter filter = new IntentFilter(); 5173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIME_TICK); 5193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIME_CHANGED); 5203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 5213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 522692356b7c392130b7f38f46a60570617c978ba75Kenny Guy getContext().registerReceiver(mIntentReceiver, filter, null, getHandler()); 5233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void registerObserver() { 5263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final ContentResolver resolver = getContext().getContentResolver(); 5279c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek if (mShowCurrentUserTime) { 5289c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek resolver.registerContentObserver(Settings.System.CONTENT_URI, true, 5299c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek mFormatChangeObserver, UserHandle.USER_ALL); 5309c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek } else { 5319c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek resolver.registerContentObserver(Settings.System.CONTENT_URI, true, 5329c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek mFormatChangeObserver); 5339c4a707912da2c954b2d3d1311b8a691ded8aa16Selim Cinek } 5343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void unregisterReceiver() { 5373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getContext().unregisterReceiver(mIntentReceiver); 5383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void unregisterObserver() { 5413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final ContentResolver resolver = getContext().getContentResolver(); 5423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy resolver.unregisterContentObserver(mFormatChangeObserver); 5433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 5453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void onTimeChanged() { 5463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime.setTimeInMillis(System.currentTimeMillis()); 5473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy setText(DateFormat.format(mFormat, mTime)); 5483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 5493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy} 550