Merge "A new clock widget to create lock screen appwidgets" into jb-mr1-dev
This commit is contained in:
@ -249,12 +249,13 @@ public class DateFormat {
|
||||
|
||||
synchronized (sLocaleLock) {
|
||||
sIs24HourLocale = locale;
|
||||
sIs24Hour = !value.equals("12");
|
||||
sIs24Hour = value.equals("24");
|
||||
}
|
||||
|
||||
return sIs24Hour;
|
||||
}
|
||||
|
||||
boolean b24 = !(value == null || value.equals("12"));
|
||||
return b24;
|
||||
return value.equals("24");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,7 +264,7 @@ public class DateFormat {
|
||||
* @param context the application context
|
||||
* @return the {@link java.text.DateFormat} object that properly formats the time.
|
||||
*/
|
||||
public static final java.text.DateFormat getTimeFormat(Context context) {
|
||||
public static java.text.DateFormat getTimeFormat(Context context) {
|
||||
boolean b24 = is24HourFormat(context);
|
||||
int res;
|
||||
|
||||
@ -283,7 +284,7 @@ public class DateFormat {
|
||||
* @param context the application context
|
||||
* @return the {@link java.text.DateFormat} object that properly formats the date.
|
||||
*/
|
||||
public static final java.text.DateFormat getDateFormat(Context context) {
|
||||
public static java.text.DateFormat getDateFormat(Context context) {
|
||||
String value = Settings.System.getString(context.getContentResolver(),
|
||||
Settings.System.DATE_FORMAT);
|
||||
|
||||
@ -353,7 +354,7 @@ public class DateFormat {
|
||||
* @param context the application context
|
||||
* @return the {@link java.text.DateFormat} object that formats the date in long form.
|
||||
*/
|
||||
public static final java.text.DateFormat getLongDateFormat(Context context) {
|
||||
public static java.text.DateFormat getLongDateFormat(Context context) {
|
||||
return java.text.DateFormat.getDateInstance(java.text.DateFormat.LONG);
|
||||
}
|
||||
|
||||
@ -363,7 +364,7 @@ public class DateFormat {
|
||||
* @param context the application context
|
||||
* @return the {@link java.text.DateFormat} object that formats the date in long form.
|
||||
*/
|
||||
public static final java.text.DateFormat getMediumDateFormat(Context context) {
|
||||
public static java.text.DateFormat getMediumDateFormat(Context context) {
|
||||
return java.text.DateFormat.getDateInstance(java.text.DateFormat.MEDIUM);
|
||||
}
|
||||
|
||||
@ -376,7 +377,7 @@ public class DateFormat {
|
||||
* not just the day, month, and year, and not necessarily in the same
|
||||
* order returned here.
|
||||
*/
|
||||
public static final char[] getDateFormatOrder(Context context) {
|
||||
public static char[] getDateFormatOrder(Context context) {
|
||||
char[] order = new char[] {DATE, MONTH, YEAR};
|
||||
String value = getDateFormatString(context);
|
||||
int index = 0;
|
||||
@ -420,7 +421,7 @@ public class DateFormat {
|
||||
* @param inTimeInMillis in milliseconds since Jan 1, 1970 GMT
|
||||
* @return a {@link CharSequence} containing the requested text
|
||||
*/
|
||||
public static final CharSequence format(CharSequence inFormat, long inTimeInMillis) {
|
||||
public static CharSequence format(CharSequence inFormat, long inTimeInMillis) {
|
||||
return format(inFormat, new Date(inTimeInMillis));
|
||||
}
|
||||
|
||||
@ -431,7 +432,7 @@ public class DateFormat {
|
||||
* @param inDate the date to format
|
||||
* @return a {@link CharSequence} containing the requested text
|
||||
*/
|
||||
public static final CharSequence format(CharSequence inFormat, Date inDate) {
|
||||
public static CharSequence format(CharSequence inFormat, Date inDate) {
|
||||
Calendar c = new GregorianCalendar();
|
||||
|
||||
c.setTime(inDate);
|
||||
@ -439,6 +440,68 @@ public class DateFormat {
|
||||
return format(inFormat, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the specified format string contains seconds.
|
||||
*
|
||||
* Always returns false if the input format is null.
|
||||
*
|
||||
* @param inFormat the format string, as described in {@link android.text.format.DateFormat}
|
||||
*
|
||||
* @return true if the format string contains {@link #SECONDS}, false otherwise
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static boolean hasSeconds(CharSequence inFormat) {
|
||||
if (inFormat == null) return false;
|
||||
|
||||
final int length = inFormat.length();
|
||||
|
||||
int c;
|
||||
int count;
|
||||
|
||||
for (int i = 0; i < length; i += count) {
|
||||
count = 1;
|
||||
c = inFormat.charAt(i);
|
||||
|
||||
if (c == QUOTE) {
|
||||
count = skipQuotedText(inFormat, i, length);
|
||||
} else if (c == SECONDS) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int skipQuotedText(CharSequence s, int i, int len) {
|
||||
if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
int count = 1;
|
||||
// skip leading quote
|
||||
i++;
|
||||
|
||||
while (i < len) {
|
||||
char c = s.charAt(i);
|
||||
|
||||
if (c == QUOTE) {
|
||||
count++;
|
||||
// QUOTEQUOTE -> QUOTE
|
||||
if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
|
||||
i++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a format string and a {@link java.util.Calendar} object, returns a CharSequence
|
||||
* containing the requested date.
|
||||
@ -446,7 +509,7 @@ public class DateFormat {
|
||||
* @param inDate the date to format
|
||||
* @return a {@link CharSequence} containing the requested text
|
||||
*/
|
||||
public static final CharSequence format(CharSequence inFormat, Calendar inDate) {
|
||||
public static CharSequence format(CharSequence inFormat, Calendar inDate) {
|
||||
SpannableStringBuilder s = new SpannableStringBuilder(inFormat);
|
||||
int c;
|
||||
int count;
|
||||
@ -545,7 +608,7 @@ public class DateFormat {
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
private static final String getMonthString(Calendar inDate, int count, int kind) {
|
||||
private static String getMonthString(Calendar inDate, int count, int kind) {
|
||||
boolean standalone = (kind == STANDALONE_MONTH);
|
||||
int month = inDate.get(Calendar.MONTH);
|
||||
|
||||
@ -563,7 +626,7 @@ public class DateFormat {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String getTimeZoneString(Calendar inDate, int count) {
|
||||
private static String getTimeZoneString(Calendar inDate, int count) {
|
||||
TimeZone tz = inDate.getTimeZone();
|
||||
|
||||
if (count < 2) { // FIXME: shouldn't this be <= 2 ?
|
||||
@ -576,7 +639,7 @@ public class DateFormat {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String formatZoneOffset(int offset, int count) {
|
||||
private static String formatZoneOffset(int offset, int count) {
|
||||
offset /= 1000; // milliseconds to seconds
|
||||
StringBuilder tb = new StringBuilder();
|
||||
|
||||
@ -595,13 +658,13 @@ public class DateFormat {
|
||||
return tb.toString();
|
||||
}
|
||||
|
||||
private static final String getYearString(Calendar inDate, int count) {
|
||||
private static String getYearString(Calendar inDate, int count) {
|
||||
int year = inDate.get(Calendar.YEAR);
|
||||
return (count <= 2) ? zeroPad(year % 100, 2)
|
||||
: String.format(Locale.getDefault(), "%d", year);
|
||||
}
|
||||
|
||||
private static final int appendQuotedText(SpannableStringBuilder s, int i, int len) {
|
||||
private static int appendQuotedText(SpannableStringBuilder s, int i, int len) {
|
||||
if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
|
||||
s.delete(i, i + 1);
|
||||
return 1;
|
||||
@ -638,7 +701,7 @@ public class DateFormat {
|
||||
return count;
|
||||
}
|
||||
|
||||
private static final String zeroPad(int inValue, int inMinDigits) {
|
||||
private static String zeroPad(int inValue, int inMinDigits) {
|
||||
return String.format(Locale.getDefault(), "%0" + inMinDigits + "d", inValue);
|
||||
}
|
||||
}
|
||||
|
@ -17697,7 +17697,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
boolean mScalingRequired;
|
||||
|
||||
/**
|
||||
* If set, ViewAncestor doesn't use its lame animation for when the window resizes.
|
||||
* If set, ViewRootImpl doesn't use its lame animation for when the window resizes.
|
||||
*/
|
||||
boolean mTurnOffWindowResizeAnim;
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
package android.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
@ -32,14 +31,12 @@ import java.util.Calendar;
|
||||
/**
|
||||
* Like AnalogClock, but digital. Shows seconds.
|
||||
*
|
||||
* FIXME: implement separate views for hours/minutes/seconds, so
|
||||
* proportional fonts don't shake rendering
|
||||
*
|
||||
* @deprecated It is recommended you use a {@link TextView} and {@link DateFormat}
|
||||
* to implement the same behavior.
|
||||
* @deprecated It is recommended you use {@link TextClock} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class DigitalClock extends TextView {
|
||||
// FIXME: implement separate views for hours/minutes/seconds, so
|
||||
// proportional fonts don't shake rendering
|
||||
|
||||
Calendar mCalendar;
|
||||
private final static String m12 = "h:mm:ss aa";
|
||||
@ -86,16 +83,16 @@ public class DigitalClock extends TextView {
|
||||
* requests a tick on the next hard-second boundary
|
||||
*/
|
||||
mTicker = new Runnable() {
|
||||
public void run() {
|
||||
if (mTickerStopped) return;
|
||||
mCalendar.setTimeInMillis(System.currentTimeMillis());
|
||||
setText(DateFormat.format(mFormat, mCalendar));
|
||||
invalidate();
|
||||
long now = SystemClock.uptimeMillis();
|
||||
long next = now + (1000 - now % 1000);
|
||||
mHandler.postAtTime(mTicker, next);
|
||||
}
|
||||
};
|
||||
public void run() {
|
||||
if (mTickerStopped) return;
|
||||
mCalendar.setTimeInMillis(System.currentTimeMillis());
|
||||
setText(DateFormat.format(mFormat, mCalendar));
|
||||
invalidate();
|
||||
long now = SystemClock.uptimeMillis();
|
||||
long next = now + (1000 - now % 1000);
|
||||
mHandler.postAtTime(mTicker, next);
|
||||
}
|
||||
};
|
||||
mTicker.run();
|
||||
}
|
||||
|
||||
@ -134,12 +131,14 @@ public class DigitalClock extends TextView {
|
||||
@Override
|
||||
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onInitializeAccessibilityEvent(event);
|
||||
//noinspection deprecation
|
||||
event.setClassName(DigitalClock.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
//noinspection deprecation
|
||||
info.setClassName(DigitalClock.class.getName());
|
||||
}
|
||||
}
|
||||
|
482
core/java/android/widget/TextClock.java
Normal file
482
core/java/android/widget/TextClock.java
Normal file
@ -0,0 +1,482 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.widget;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static android.view.ViewDebug.ExportedProperty;
|
||||
import static android.widget.RemoteViews.*;
|
||||
|
||||
/**
|
||||
* <p><code>TextClock</code> can display the current date and/or time as
|
||||
* a formatted string.</p>
|
||||
*
|
||||
* <p>This view honors the 24-hour format system setting. As such, it is
|
||||
* possible and recommended to provide two different formatting patterns:
|
||||
* one to display the date/time in 24-hour mode and one to display the
|
||||
* date/time in 12-hour mode.</p>
|
||||
*
|
||||
* <p>It is possible to determine whether the system is currently in
|
||||
* 24-hour mode by calling {@link #is24HourModeEnabled()}.</p>
|
||||
*
|
||||
* <p>The rules used by this widget to decide how to format the date and
|
||||
* time are the following:</p>
|
||||
* <ul>
|
||||
* <li>In 24-hour mode:
|
||||
* <ul>
|
||||
* <li>Use the value returned by {@link #getFormat24Hour()} when non-null</li>
|
||||
* <li>Otherwise, use the value returned by {@link #getFormat12Hour()} when non-null</li>
|
||||
* <li>Otherwise, use {@link #DEFAULT_FORMAT_24_HOUR}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>In 12-hour mode:
|
||||
* <ul>
|
||||
* <li>Use the value returned by {@link #getFormat12Hour()} when non-null</li>
|
||||
* <li>Otherwise, use the value returned by {@link #getFormat24Hour()} when non-null</li>
|
||||
* <li>Otherwise, use {@link #DEFAULT_FORMAT_12_HOUR}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>The {@link CharSequence} instances used as formatting patterns when calling either
|
||||
* {@link #setFormat24Hour(CharSequence)} or {@link #setFormat12Hour(CharSequence)} can
|
||||
* contain styling information. To do so, use a {@link android.text.Spanned} object.</p>
|
||||
*
|
||||
* @attr ref android.R.styleable#TextClock_format12Hour
|
||||
* @attr ref android.R.styleable#TextClock_format24Hour
|
||||
* @attr ref android.R.styleable#TextClock_timeZone
|
||||
*/
|
||||
@RemoteView
|
||||
public class TextClock extends TextView {
|
||||
/**
|
||||
* The default formatting pattern in 12-hour mode. This pattenr is used
|
||||
* if {@link #setFormat12Hour(CharSequence)} is called with a null pattern
|
||||
* or if no pattern was specified when creating an instance of this class.
|
||||
*
|
||||
* This default pattern shows only the time, hours and minutes, and an am/pm
|
||||
* indicator.
|
||||
*
|
||||
* @see #setFormat12Hour(CharSequence)
|
||||
* @see #getFormat12Hour()
|
||||
*/
|
||||
public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm aa";
|
||||
|
||||
/**
|
||||
* The default formatting pattern in 24-hour mode. This pattenr is used
|
||||
* if {@link #setFormat24Hour(CharSequence)} is called with a null pattern
|
||||
* or if no pattern was specified when creating an instance of this class.
|
||||
*
|
||||
* This default pattern shows only the time, hours and minutes.
|
||||
*
|
||||
* @see #setFormat24Hour(CharSequence)
|
||||
* @see #getFormat24Hour()
|
||||
*/
|
||||
public static final CharSequence DEFAULT_FORMAT_24_HOUR = "k:mm";
|
||||
|
||||
private CharSequence mFormat12 = DEFAULT_FORMAT_12_HOUR;
|
||||
private CharSequence mFormat24 = DEFAULT_FORMAT_24_HOUR;
|
||||
|
||||
@ExportedProperty
|
||||
private CharSequence mFormat;
|
||||
@ExportedProperty
|
||||
private boolean mHasSeconds;
|
||||
|
||||
private boolean mAttached;
|
||||
|
||||
private Calendar mTime;
|
||||
private String mTimeZone;
|
||||
|
||||
private final ContentObserver mFormatChangeObserver = new ContentObserver(new Handler()) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
chooseFormat();
|
||||
onTimeChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
chooseFormat();
|
||||
onTimeChanged();
|
||||
}
|
||||
};
|
||||
|
||||
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (mTimeZone == null) {
|
||||
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
|
||||
final String timeZone = intent.getStringExtra("time-zone");
|
||||
createTime(timeZone);
|
||||
}
|
||||
onTimeChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mTicker = new Runnable() {
|
||||
public void run() {
|
||||
onTimeChanged();
|
||||
|
||||
long now = SystemClock.uptimeMillis();
|
||||
long next = now + (1000 - now % 1000);
|
||||
|
||||
getHandler().postAtTime(mTicker, next);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new clock using the default patterns
|
||||
* {@link #DEFAULT_FORMAT_24_HOUR} and {@link #DEFAULT_FORMAT_12_HOUR}
|
||||
* respectively for the 24-hour and 12-hour modes.
|
||||
*
|
||||
* @param context The Context the view is running in, through which it can
|
||||
* access the current theme, resources, etc.
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public TextClock(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new clock inflated from XML. This object's properties are
|
||||
* intialized from the attributes specified in XML.
|
||||
*
|
||||
* This constructor uses a default style of 0, so the only attribute values
|
||||
* applied are those in the Context's Theme and the given AttributeSet.
|
||||
*
|
||||
* @param context The Context the view is running in, through which it can
|
||||
* access the current theme, resources, etc.
|
||||
* @param attrs The attributes of the XML tag that is inflating the view
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public TextClock(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new clock inflated from XML. This object's properties are
|
||||
* intialized from the attributes specified in XML.
|
||||
*
|
||||
* @param context The Context the view is running in, through which it can
|
||||
* access the current theme, resources, etc.
|
||||
* @param attrs The attributes of the XML tag that is inflating the view
|
||||
* @param defStyle The default style to apply to this view. If 0, no style
|
||||
* will be applied (beyond what is included in the theme). This may
|
||||
* either be an attribute resource, whose value will be retrieved
|
||||
* from the current theme, or an explicit style resource
|
||||
*/
|
||||
public TextClock(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextClock, defStyle, 0);
|
||||
try {
|
||||
CharSequence format;
|
||||
|
||||
format = a.getText(R.styleable.TextClock_format12Hour);
|
||||
mFormat12 = format == null ? DEFAULT_FORMAT_12_HOUR : format;
|
||||
|
||||
format = a.getText(R.styleable.TextClock_format24Hour);
|
||||
mFormat24 = format == null ? DEFAULT_FORMAT_24_HOUR : format;
|
||||
|
||||
mTimeZone = a.getString(R.styleable.TextClock_timeZone);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
createTime(mTimeZone);
|
||||
// Wait until onAttachedToWindow() to handle the ticker
|
||||
chooseFormat(false);
|
||||
}
|
||||
|
||||
private void createTime(String timeZone) {
|
||||
if (timeZone != null) {
|
||||
mTime = Calendar.getInstance(TimeZone.getTimeZone(timeZone));
|
||||
} else {
|
||||
mTime = Calendar.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the formatting pattern used to display the date and/or time
|
||||
* in 12-hour mode. The formatting pattern syntax is described in
|
||||
* {@link DateFormat}.
|
||||
*
|
||||
* @return A {@link CharSequence} or null.
|
||||
*
|
||||
* @see #setFormat12Hour(CharSequence)
|
||||
* @see #is24HourModeEnabled()
|
||||
*/
|
||||
@ExportedProperty
|
||||
public CharSequence getFormat12Hour() {
|
||||
return mFormat12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the formatting pattern used to display the date and/or time
|
||||
* in 12-hour mode. The formatting pattern syntax is described in
|
||||
* {@link DateFormat}.
|
||||
*
|
||||
* If this pattern is set to null, {@link #getFormat24Hour()} will be used
|
||||
* even in 12-hour mode. If both 24-hour and 12-hour formatting patterns
|
||||
* are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
|
||||
* {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
|
||||
*
|
||||
* @param format A date/time formatting pattern as described in {@link DateFormat}
|
||||
*
|
||||
* @see #getFormat12Hour()
|
||||
* @see #is24HourModeEnabled()
|
||||
* @see #DEFAULT_FORMAT_12_HOUR
|
||||
* @see DateFormat
|
||||
*
|
||||
* @attr ref android.R.styleable#TextClock_format12Hour
|
||||
*/
|
||||
public void setFormat12Hour(CharSequence format) {
|
||||
mFormat12 = format;
|
||||
|
||||
chooseFormat();
|
||||
onTimeChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the formatting pattern used to display the date and/or time
|
||||
* in 24-hour mode. The formatting pattern syntax is described in
|
||||
* {@link DateFormat}.
|
||||
*
|
||||
* @return A {@link CharSequence} or null.
|
||||
*
|
||||
* @see #setFormat24Hour(CharSequence)
|
||||
* @see #is24HourModeEnabled()
|
||||
*/
|
||||
@ExportedProperty
|
||||
public CharSequence getFormat24Hour() {
|
||||
return mFormat24;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the formatting pattern used to display the date and/or time
|
||||
* in 24-hour mode. The formatting pattern syntax is described in
|
||||
* {@link DateFormat}.
|
||||
*
|
||||
* If this pattern is set to null, {@link #getFormat12Hour()} will be used
|
||||
* even in 24-hour mode. If both 24-hour and 12-hour formatting patterns
|
||||
* are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
|
||||
* {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
|
||||
*
|
||||
* @param format A date/time formatting pattern as described in {@link DateFormat}
|
||||
*
|
||||
* @see #getFormat24Hour()
|
||||
* @see #is24HourModeEnabled()
|
||||
* @see #DEFAULT_FORMAT_24_HOUR
|
||||
* @see DateFormat
|
||||
*
|
||||
* @attr ref android.R.styleable#TextClock_format24Hour
|
||||
*/
|
||||
public void setFormat24Hour(CharSequence format) {
|
||||
mFormat24 = format;
|
||||
|
||||
chooseFormat();
|
||||
onTimeChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the system is currently using the 24-hour mode.
|
||||
*
|
||||
* When the system is in 24-hour mode, this view will use the pattern
|
||||
* returned by {@link #getFormat24Hour()}. In 12-hour mode, the pattern
|
||||
* returned by {@link #getFormat12Hour()} is used instead.
|
||||
*
|
||||
* If either one of the formats is null, the other format is used. If
|
||||
* both formats are null, the default values {@link #DEFAULT_FORMAT_12_HOUR}
|
||||
* and {@link #DEFAULT_FORMAT_24_HOUR} are used instead.
|
||||
*
|
||||
* @return true if time should be displayed in 24-hour format, false if it
|
||||
* should be displayed in 12-hour format.
|
||||
*
|
||||
* @see #setFormat12Hour(CharSequence)
|
||||
* @see #getFormat12Hour()
|
||||
* @see #setFormat24Hour(CharSequence)
|
||||
* @see #getFormat24Hour()
|
||||
*/
|
||||
public boolean is24HourModeEnabled() {
|
||||
return DateFormat.is24HourFormat(getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates which time zone is currently used by this view.
|
||||
*
|
||||
* @return The ID of the current time zone or null if the default time zone,
|
||||
* as set by the user, must be used
|
||||
*
|
||||
* @see TimeZone
|
||||
* @see java.util.TimeZone#getAvailableIDs()
|
||||
* @see #setTimeZone(String)
|
||||
*/
|
||||
public String getTimeZone() {
|
||||
return mTimeZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified time zone to use in this clock. When the time zone
|
||||
* is set through this method, system time zone changes (when the user
|
||||
* sets the time zone in settings for instance) will be ignored.
|
||||
*
|
||||
* @param timeZone The desired time zone's ID as specified in {@link TimeZone}
|
||||
* or null to user the time zone specified by the user
|
||||
* (system time zone)
|
||||
*
|
||||
* @see #getTimeZone()
|
||||
* @see java.util.TimeZone#getAvailableIDs()
|
||||
* @see TimeZone#getTimeZone(String)
|
||||
*
|
||||
* @attr ref android.R.styleable#TextClock_timeZone
|
||||
*/
|
||||
public void setTimeZone(String timeZone) {
|
||||
mTimeZone = timeZone;
|
||||
|
||||
createTime(timeZone);
|
||||
onTimeChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()}
|
||||
* depending on whether the user has selected 24-hour format.
|
||||
*
|
||||
* Calling this method does not schedule or unschedule the time ticker.
|
||||
*/
|
||||
private void chooseFormat() {
|
||||
chooseFormat(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()}
|
||||
* depending on whether the user has selected 24-hour format.
|
||||
*
|
||||
* @param handleTicker true if calling this method should schedule/unschedule the
|
||||
* time ticker, false otherwise
|
||||
*/
|
||||
private void chooseFormat(boolean handleTicker) {
|
||||
final boolean format24Requested = is24HourModeEnabled();
|
||||
|
||||
if (format24Requested) {
|
||||
mFormat = abc(mFormat24, mFormat12, DEFAULT_FORMAT_24_HOUR);
|
||||
} else {
|
||||
mFormat = abc(mFormat12, mFormat24, DEFAULT_FORMAT_12_HOUR);
|
||||
}
|
||||
|
||||
boolean hadSeconds = mHasSeconds;
|
||||
mHasSeconds = DateFormat.hasSeconds(mFormat);
|
||||
|
||||
if (handleTicker) {
|
||||
if (hadSeconds != mHasSeconds) {
|
||||
if (hadSeconds) getHandler().removeCallbacks(mTicker);
|
||||
else mTicker.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a if not null, else return b if not null, else return c.
|
||||
*/
|
||||
private static CharSequence abc(CharSequence a, CharSequence b, CharSequence c) {
|
||||
return a == null ? (b == null ? c : b) : a;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
if (!mAttached) {
|
||||
mAttached = true;
|
||||
|
||||
registerReceiver();
|
||||
registerObserver();
|
||||
|
||||
createTime(mTimeZone);
|
||||
|
||||
if (mHasSeconds) {
|
||||
mTicker.run();
|
||||
} else {
|
||||
onTimeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
|
||||
if (mAttached) {
|
||||
unregisterReceiver();
|
||||
unregisterObserver();
|
||||
|
||||
getHandler().removeCallbacks(mTicker);
|
||||
|
||||
mAttached = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void registerReceiver() {
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
|
||||
filter.addAction(Intent.ACTION_TIME_TICK);
|
||||
filter.addAction(Intent.ACTION_TIME_CHANGED);
|
||||
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
|
||||
|
||||
getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
|
||||
}
|
||||
|
||||
private void registerObserver() {
|
||||
final ContentResolver resolver = getContext().getContentResolver();
|
||||
resolver.registerContentObserver(Settings.System.CONTENT_URI, true, mFormatChangeObserver);
|
||||
}
|
||||
|
||||
private void unregisterReceiver() {
|
||||
getContext().unregisterReceiver(mIntentReceiver);
|
||||
}
|
||||
|
||||
private void unregisterObserver() {
|
||||
final ContentResolver resolver = getContext().getContentResolver();
|
||||
resolver.unregisterContentObserver(mFormatChangeObserver);
|
||||
}
|
||||
|
||||
private void onTimeChanged() {
|
||||
mTime.setTimeInMillis(System.currentTimeMillis());
|
||||
setText(DateFormat.format(mFormat, mTime));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user