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 393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport static android.view.ViewDebug.ExportedProperty; 403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guyimport static android.widget.RemoteViews.*; 413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy/** 433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p><code>TextClock</code> can display the current date and/or time as 443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * a formatted string.</p> 453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>This view honors the 24-hour format system setting. As such, it is 473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * possible and recommended to provide two different formatting patterns: 483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * one to display the date/time in 24-hour mode and one to display the 493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * date/time in 12-hour mode.</p> 503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>It is possible to determine whether the system is currently in 523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 24-hour mode by calling {@link #is24HourModeEnabled()}.</p> 533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>The rules used by this widget to decide how to format the date and 553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * time are the following:</p> 563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>In 24-hour mode: 583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Use the value returned by {@link #getFormat24Hour()} when non-null</li> 603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use the value returned by {@link #getFormat12Hour()} when non-null</li> 613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use {@link #DEFAULT_FORMAT_24_HOUR}</li> 623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </li> 643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>In 12-hour mode: 653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <ul> 663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Use the value returned by {@link #getFormat12Hour()} when non-null</li> 673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use the value returned by {@link #getFormat24Hour()} when non-null</li> 683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <li>Otherwise, use {@link #DEFAULT_FORMAT_12_HOUR}</li> 693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </li> 713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * </ul> 723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * <p>The {@link CharSequence} instances used as formatting patterns when calling either 743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link #setFormat24Hour(CharSequence)} or {@link #setFormat12Hour(CharSequence)} can 753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * contain styling information. To do so, use a {@link android.text.Spanned} object.</p> 763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format12Hour 783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format24Hour 793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_timeZone 803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy@RemoteView 823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guypublic class TextClock extends TextView { 833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * The default formatting pattern in 12-hour mode. This pattenr is used 853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * if {@link #setFormat12Hour(CharSequence)} is called with a null pattern 863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or if no pattern was specified when creating an instance of this class. 873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This default pattern shows only the time, hours and minutes, and an am/pm 893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * indicator. 903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat12Hour(CharSequence) 923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat12Hour() 933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm aa"; 953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * The default formatting pattern in 24-hour mode. This pattenr is used 983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * if {@link #setFormat24Hour(CharSequence)} is called with a null pattern 993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or if no pattern was specified when creating an instance of this class. 1003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This default pattern shows only the time, hours and minutes. 1023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat24Hour(CharSequence) 1043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat24Hour() 1053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public static final CharSequence DEFAULT_FORMAT_24_HOUR = "k:mm"; 1073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private CharSequence mFormat12 = DEFAULT_FORMAT_12_HOUR; 1093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private CharSequence mFormat24 = DEFAULT_FORMAT_24_HOUR; 1103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 1123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private CharSequence mFormat; 1133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 1143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private boolean mHasSeconds; 1153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private boolean mAttached; 1173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private Calendar mTime; 1193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private String mTimeZone; 1203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final ContentObserver mFormatChangeObserver = new ContentObserver(new Handler()) { 1223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onChange(boolean selfChange) { 1243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 1253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onChange(boolean selfChange, Uri uri) { 1303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 1313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 1363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 1373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void onReceive(Context context, Intent intent) { 138a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (mTimeZone == null && Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 139a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy final String timeZone = intent.getStringExtra("time-zone"); 140a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy createTime(timeZone); 1413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 142a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy onTimeChanged(); 1433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private final Runnable mTicker = new Runnable() { 1473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void run() { 1483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 1493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy long now = SystemClock.uptimeMillis(); 1513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy long next = now + (1000 - now % 1000); 1523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getHandler().postAtTime(mTicker, next); 1543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy }; 1563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 1583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Creates a new clock using the default patterns 1593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link #DEFAULT_FORMAT_24_HOUR} and {@link #DEFAULT_FORMAT_12_HOUR} 1603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * respectively for the 24-hour and 12-hour modes. 1613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 1643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @SuppressWarnings("UnusedDeclaration") 1663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context) { 1673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super(context); 1683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy init(); 1693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 1723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Creates a new clock inflated from XML. This object's properties are 1733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * intialized from the attributes specified in XML. 1743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * This constructor uses a default style of 0, so the only attribute values 1763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * applied are those in the Context's Theme and the given AttributeSet. 1773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 1803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param attrs The attributes of the XML tag that is inflating the view 1813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @SuppressWarnings("UnusedDeclaration") 1833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context, AttributeSet attrs) { 1843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy this(context, attrs, 0); 1853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 1863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 1873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 1883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Creates a new clock inflated from XML. This object's properties are 1893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * intialized from the attributes specified in XML. 1903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 1913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param context The Context the view is running in, through which it can 1923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * access the current theme, resources, etc. 1933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param attrs The attributes of the XML tag that is inflating the view 1943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param defStyle The default style to apply to this view. If 0, no style 1953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * will be applied (beyond what is included in the theme). This may 1963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * either be an attribute resource, whose value will be retrieved 1973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * from the current theme, or an explicit style resource 1983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 1993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public TextClock(Context context, AttributeSet attrs, int defStyle) { 2003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super(context, attrs, defStyle); 2013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextClock, defStyle, 0); 2033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy try { 2043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy CharSequence format; 2053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy format = a.getText(R.styleable.TextClock_format12Hour); 2073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat12 = format == null ? DEFAULT_FORMAT_12_HOUR : format; 2083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy format = a.getText(R.styleable.TextClock_format24Hour); 2103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat24 = format == null ? DEFAULT_FORMAT_24_HOUR : format; 2113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTimeZone = a.getString(R.styleable.TextClock_timeZone); 2133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } finally { 2143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy a.recycle(); 2153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy init(); 2183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void init() { 2213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(mTimeZone); 2223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy // Wait until onAttachedToWindow() to handle the ticker 2233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(false); 2243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void createTime(String timeZone) { 2273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (timeZone != null) { 2283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime = Calendar.getInstance(TimeZone.getTimeZone(timeZone)); 2293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 2303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime = Calendar.getInstance(); 2313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 2353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns the formatting pattern used to display the date and/or time 2363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 12-hour mode. The formatting pattern syntax is described in 2373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 2383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return A {@link CharSequence} or null. 2403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat12Hour(CharSequence) 2423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 2433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 2443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 2453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public CharSequence getFormat12Hour() { 2463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mFormat12; 2473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 2503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Specifies the formatting pattern used to display the date and/or time 2513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 12-hour mode. The formatting pattern syntax is described in 2523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 2533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * If this pattern is set to null, {@link #getFormat24Hour()} will be used 2553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns 2563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and 2573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead. 2583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param format A date/time formatting pattern as described in {@link DateFormat} 2603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat12Hour() 2623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 2633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #DEFAULT_FORMAT_12_HOUR 2643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see DateFormat 2653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format12Hour 2673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 268a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 2693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setFormat12Hour(CharSequence format) { 2703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat12 = format; 2713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 2733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 2743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 2773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns the formatting pattern used to display the date and/or time 2783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 24-hour mode. The formatting pattern syntax is described in 2793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 2803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return A {@link CharSequence} or null. 2823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat24Hour(CharSequence) 2843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 2853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 2863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @ExportedProperty 2873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public CharSequence getFormat24Hour() { 2883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mFormat24; 2893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 2903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 2913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 2923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Specifies the formatting pattern used to display the date and/or time 2933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * in 24-hour mode. The formatting pattern syntax is described in 2943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link DateFormat}. 2953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 2963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * If this pattern is set to null, {@link #getFormat12Hour()} will be used 2973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * even in 24-hour mode. If both 24-hour and 12-hour formatting patterns 2983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and 2993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead. 3003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param format A date/time formatting pattern as described in {@link DateFormat} 3023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat24Hour() 3043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #is24HourModeEnabled() 3053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #DEFAULT_FORMAT_24_HOUR 3063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see DateFormat 3073d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3083d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_format24Hour 3093d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 310a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 3113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setFormat24Hour(CharSequence format) { 3123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat24 = format; 3133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(); 3153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 3163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Indicates whether the system is currently using the 24-hour mode. 3203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * When the system is in 24-hour mode, this view will use the pattern 3223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * returned by {@link #getFormat24Hour()}. In 12-hour mode, the pattern 3233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * returned by {@link #getFormat12Hour()} is used instead. 3243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * If either one of the formats is null, the other format is used. If 3263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * both formats are null, the default values {@link #DEFAULT_FORMAT_12_HOUR} 3273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * and {@link #DEFAULT_FORMAT_24_HOUR} are used instead. 3283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return true if time should be displayed in 24-hour format, false if it 3303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * should be displayed in 12-hour format. 3313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat12Hour(CharSequence) 3333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat12Hour() 3343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setFormat24Hour(CharSequence) 3353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getFormat24Hour() 3363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public boolean is24HourModeEnabled() { 3383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return DateFormat.is24HourFormat(getContext()); 3393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Indicates which time zone is currently used by this view. 3433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @return The ID of the current time zone or null if the default time zone, 3453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * as set by the user, must be used 3463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see TimeZone 3483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see java.util.TimeZone#getAvailableIDs() 3493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #setTimeZone(String) 3503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public String getTimeZone() { 3523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return mTimeZone; 3533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Sets the specified time zone to use in this clock. When the time zone 3573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * is set through this method, system time zone changes (when the user 3583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * sets the time zone in settings for instance) will be ignored. 3593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param timeZone The desired time zone's ID as specified in {@link TimeZone} 3613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * or null to user the time zone specified by the user 3623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * (system time zone) 3633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see #getTimeZone() 3653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see java.util.TimeZone#getAvailableIDs() 3663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @see TimeZone#getTimeZone(String) 3673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @attr ref android.R.styleable#TextClock_timeZone 3693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 370a9cfe677eec0324a94509c6a5d29cec5b8a7a7cfRomain Guy @RemotableViewMethod 3713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy public void setTimeZone(String timeZone) { 3723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTimeZone = timeZone; 3733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(timeZone); 3753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 3763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()} 3803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * depending on whether the user has selected 24-hour format. 3813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Calling this method does not schedule or unschedule the time ticker. 3833d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3843d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void chooseFormat() { 3853d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy chooseFormat(true); 3863d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 3873d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3883d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 3893d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()} 3903d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * depending on whether the user has selected 24-hour format. 3913d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * 3923d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * @param handleTicker true if calling this method should schedule/unschedule the 3933d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * time ticker, false otherwise 3943d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 3953d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void chooseFormat(boolean handleTicker) { 3963d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final boolean format24Requested = is24HourModeEnabled(); 3973d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 3983d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (format24Requested) { 3993d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat = abc(mFormat24, mFormat12, DEFAULT_FORMAT_24_HOUR); 4003d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 4013d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mFormat = abc(mFormat12, mFormat24, DEFAULT_FORMAT_12_HOUR); 4023d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4033d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4043d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy boolean hadSeconds = mHasSeconds; 4053d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mHasSeconds = DateFormat.hasSeconds(mFormat); 4063d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 407a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (handleTicker && mAttached && hadSeconds != mHasSeconds) { 408a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy if (hadSeconds) getHandler().removeCallbacks(mTicker); 409a76f7db323598f78512bbbdf2fb89248c9e317e5Romain Guy else mTicker.run(); 4103d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4113d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4123d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4133d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy /** 4143d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy * Returns a if not null, else return b if not null, else return c. 4153d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy */ 4163d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private static CharSequence abc(CharSequence a, CharSequence b, CharSequence c) { 4173d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy return a == null ? (b == null ? c : b) : a; 4183d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4193d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4203d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 4213d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy protected void onAttachedToWindow() { 4223d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super.onAttachedToWindow(); 4233d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4243d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (!mAttached) { 4253d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mAttached = true; 4263d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4273d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy registerReceiver(); 4283d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy registerObserver(); 4293d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4303d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy createTime(mTimeZone); 4313d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4323d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (mHasSeconds) { 4333d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTicker.run(); 4343d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } else { 4353d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy onTimeChanged(); 4363d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4373d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4383d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4393d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4403d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy @Override 4413d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy protected void onDetachedFromWindow() { 4423d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy super.onDetachedFromWindow(); 4433d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4443d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy if (mAttached) { 4453d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy unregisterReceiver(); 4463d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy unregisterObserver(); 4473d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4483d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getHandler().removeCallbacks(mTicker); 4493d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4503d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mAttached = false; 4513d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4523d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4533d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4543d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void registerReceiver() { 4553d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final IntentFilter filter = new IntentFilter(); 4563d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4573d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIME_TICK); 4583d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIME_CHANGED); 4593d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 4603d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4613d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getContext().registerReceiver(mIntentReceiver, filter, null, getHandler()); 4623d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4633d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4643d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void registerObserver() { 4653d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final ContentResolver resolver = getContext().getContentResolver(); 4663d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy resolver.registerContentObserver(Settings.System.CONTENT_URI, true, mFormatChangeObserver); 4673d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4683d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4693d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void unregisterReceiver() { 4703d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy getContext().unregisterReceiver(mIntentReceiver); 4713d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4723d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4733d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void unregisterObserver() { 4743d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy final ContentResolver resolver = getContext().getContentResolver(); 4753d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy resolver.unregisterContentObserver(mFormatChangeObserver); 4763d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4773d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy 4783d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy private void onTimeChanged() { 4793d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy mTime.setTimeInMillis(System.currentTimeMillis()); 4803d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy setText(DateFormat.format(mFormat, mTime)); 4813d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy } 4823d1728c03a0cd1aaed6bc81c97de27d62c771a6eRomain Guy} 483