Merge "Switch widgets away from android.text.format.Time" am: db31e6d07a am: 8d96e17940 am: 19d4f4eb32
am: cc83885699
Change-Id: I65dbe328322adc5b17b93de7bb1ceb095e576582
This commit is contained in:
@@ -26,12 +26,14 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews.RemoteView;
|
||||
|
||||
import java.util.TimeZone;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* This widget display an analogic clock with two hands for hours and
|
||||
@@ -45,7 +47,7 @@ import java.util.TimeZone;
|
||||
@RemoteView
|
||||
@Deprecated
|
||||
public class AnalogClock extends View {
|
||||
private Time mCalendar;
|
||||
private Clock mClock;
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private Drawable mHourHand;
|
||||
@@ -99,7 +101,7 @@ public class AnalogClock extends View {
|
||||
mMinuteHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
|
||||
}
|
||||
|
||||
mCalendar = new Time();
|
||||
mClock = Clock.systemDefaultZone();
|
||||
|
||||
mDialWidth = mDial.getIntrinsicWidth();
|
||||
mDialHeight = mDial.getIntrinsicHeight();
|
||||
@@ -132,7 +134,7 @@ public class AnalogClock extends View {
|
||||
// in the main thread, therefore the receiver can't run before this method returns.
|
||||
|
||||
// The time zone may have changed while the receiver wasn't registered, so update the Time
|
||||
mCalendar = new Time();
|
||||
mClock = Clock.systemDefaultZone();
|
||||
|
||||
// Make sure we update to the current time
|
||||
onTimeChanged();
|
||||
@@ -241,17 +243,18 @@ public class AnalogClock extends View {
|
||||
}
|
||||
|
||||
private void onTimeChanged() {
|
||||
mCalendar.setToNow();
|
||||
long nowMillis = mClock.millis();
|
||||
LocalDateTime localDateTime = toLocalDateTime(nowMillis, mClock.getZone());
|
||||
|
||||
int hour = mCalendar.hour;
|
||||
int minute = mCalendar.minute;
|
||||
int second = mCalendar.second;
|
||||
int hour = localDateTime.getHour();
|
||||
int minute = localDateTime.getMinute();
|
||||
int second = localDateTime.getSecond();
|
||||
|
||||
mMinutes = minute + second / 60.0f;
|
||||
mHour = hour + mMinutes / 60.0f;
|
||||
mChanged = true;
|
||||
|
||||
updateContentDescription(mCalendar);
|
||||
updateContentDescription(nowMillis);
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
||||
@@ -259,7 +262,7 @@ public class AnalogClock extends View {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
|
||||
String tz = intent.getStringExtra("time-zone");
|
||||
mCalendar = new Time(TimeZone.getTimeZone(tz).getID());
|
||||
mClock = Clock.system(ZoneId.of(tz));
|
||||
}
|
||||
|
||||
onTimeChanged();
|
||||
@@ -268,10 +271,17 @@ public class AnalogClock extends View {
|
||||
}
|
||||
};
|
||||
|
||||
private void updateContentDescription(Time time) {
|
||||
private void updateContentDescription(long timeMillis) {
|
||||
final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
|
||||
String contentDescription = DateUtils.formatDateTime(mContext,
|
||||
time.toMillis(false), flags);
|
||||
String contentDescription = DateUtils.formatDateTime(mContext, timeMillis, flags);
|
||||
setContentDescription(contentDescription);
|
||||
}
|
||||
|
||||
private static LocalDateTime toLocalDateTime(long timeMillis, ZoneId zoneId) {
|
||||
// java.time types like LocalDateTime / Instant can support the full range of "long millis"
|
||||
// with room to spare so we do not need to worry about overflow / underflow and the
|
||||
// resulting exceptions while the input to this class is a long.
|
||||
Instant instant = Instant.ofEpochMilli(timeMillis);
|
||||
return LocalDateTime.ofInstant(instant, zoneId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.YEAR_IN_MILLIS;
|
||||
import static android.text.format.Time.getJulianDay;
|
||||
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.app.ActivityThread;
|
||||
@@ -32,7 +31,6 @@ import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.text.format.Time;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.inspector.InspectableProperty;
|
||||
@@ -41,10 +39,14 @@ import android.widget.RemoteViews.RemoteView;
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.JulianFields;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
//
|
||||
// TODO
|
||||
@@ -63,8 +65,9 @@ public class DateTimeView extends TextView {
|
||||
private static final int SHOW_TIME = 0;
|
||||
private static final int SHOW_MONTH_DAY_YEAR = 1;
|
||||
|
||||
Date mTime;
|
||||
long mTimeMillis;
|
||||
private long mTimeMillis;
|
||||
// The LocalDateTime equivalent of mTimeMillis but truncated to minute, i.e. no seconds / nanos.
|
||||
private LocalDateTime mLocalTime;
|
||||
|
||||
int mLastDisplay = -1;
|
||||
DateFormat mLastFormat;
|
||||
@@ -128,11 +131,10 @@ public class DateTimeView extends TextView {
|
||||
|
||||
@android.view.RemotableViewMethod
|
||||
@UnsupportedAppUsage
|
||||
public void setTime(long time) {
|
||||
Time t = new Time();
|
||||
t.set(time);
|
||||
mTimeMillis = t.toMillis(false);
|
||||
mTime = new Date(t.year-1900, t.month, t.monthDay, t.hour, t.minute, 0);
|
||||
public void setTime(long timeMillis) {
|
||||
mTimeMillis = timeMillis;
|
||||
LocalDateTime dateTime = toLocalDateTime(timeMillis, ZoneId.systemDefault());
|
||||
mLocalTime = dateTime.withSecond(0);
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -165,7 +167,7 @@ public class DateTimeView extends TextView {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
void update() {
|
||||
if (mTime == null || getVisibility() == GONE) {
|
||||
if (mLocalTime == null || getVisibility() == GONE) {
|
||||
return;
|
||||
}
|
||||
if (mShowRelativeTime) {
|
||||
@@ -174,31 +176,27 @@ public class DateTimeView extends TextView {
|
||||
}
|
||||
|
||||
int display;
|
||||
Date time = mTime;
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
|
||||
Time t = new Time();
|
||||
t.set(mTimeMillis);
|
||||
t.second = 0;
|
||||
// localTime is the local time for mTimeMillis but at zero seconds past the minute.
|
||||
LocalDateTime localTime = mLocalTime;
|
||||
LocalDateTime localStartOfDay =
|
||||
LocalDateTime.of(localTime.toLocalDate(), LocalTime.MIDNIGHT);
|
||||
LocalDateTime localTomorrowStartOfDay = localStartOfDay.plusDays(1);
|
||||
// now is current local time but at zero seconds past the minute.
|
||||
LocalDateTime localNow = LocalDateTime.now(zoneId).withSecond(0);
|
||||
|
||||
t.hour -= 12;
|
||||
long twelveHoursBefore = t.toMillis(false);
|
||||
t.hour += 12;
|
||||
long twelveHoursAfter = t.toMillis(false);
|
||||
t.hour = 0;
|
||||
t.minute = 0;
|
||||
long midnightBefore = t.toMillis(false);
|
||||
t.monthDay++;
|
||||
long midnightAfter = t.toMillis(false);
|
||||
|
||||
long nowMillis = System.currentTimeMillis();
|
||||
t.set(nowMillis);
|
||||
t.second = 0;
|
||||
nowMillis = t.normalize(false);
|
||||
long twelveHoursBefore = toEpochMillis(localTime.minusHours(12), zoneId);
|
||||
long twelveHoursAfter = toEpochMillis(localTime.plusHours(12), zoneId);
|
||||
long midnightBefore = toEpochMillis(localStartOfDay, zoneId);
|
||||
long midnightAfter = toEpochMillis(localTomorrowStartOfDay, zoneId);
|
||||
long time = toEpochMillis(localTime, zoneId);
|
||||
long now = toEpochMillis(localNow, zoneId);
|
||||
|
||||
// Choose the display mode
|
||||
choose_display: {
|
||||
if ((nowMillis >= midnightBefore && nowMillis < midnightAfter)
|
||||
|| (nowMillis >= twelveHoursBefore && nowMillis < twelveHoursAfter)) {
|
||||
if ((now >= midnightBefore && now < midnightAfter)
|
||||
|| (now >= twelveHoursBefore && now < twelveHoursAfter)) {
|
||||
display = SHOW_TIME;
|
||||
break choose_display;
|
||||
}
|
||||
@@ -227,7 +225,7 @@ public class DateTimeView extends TextView {
|
||||
}
|
||||
|
||||
// Set the text
|
||||
String text = format.format(mTime);
|
||||
String text = format.format(new Date(time));
|
||||
setText(text);
|
||||
|
||||
// Schedule the next update
|
||||
@@ -236,7 +234,7 @@ public class DateTimeView extends TextView {
|
||||
mUpdateTimeMillis = twelveHoursAfter > midnightAfter ? twelveHoursAfter : midnightAfter;
|
||||
} else {
|
||||
// Currently showing the date
|
||||
if (mTimeMillis < nowMillis) {
|
||||
if (mTimeMillis < now) {
|
||||
// If the time is in the past, don't schedule an update
|
||||
mUpdateTimeMillis = 0;
|
||||
} else {
|
||||
@@ -277,15 +275,18 @@ public class DateTimeView extends TextView {
|
||||
millisIncrease = HOUR_IN_MILLIS;
|
||||
} else if (duration < YEAR_IN_MILLIS) {
|
||||
// In weird cases it can become 0 because of daylight savings
|
||||
TimeZone timeZone = TimeZone.getDefault();
|
||||
count = Math.max(Math.abs(dayDistance(timeZone, mTimeMillis, now)), 1);
|
||||
LocalDateTime localDateTime = mLocalTime;
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
LocalDateTime localNow = toLocalDateTime(now, zoneId);
|
||||
|
||||
count = Math.max(Math.abs(dayDistance(localDateTime, localNow)), 1);
|
||||
result = String.format(getContext().getResources().getQuantityString(past
|
||||
? com.android.internal.R.plurals.duration_days_shortest
|
||||
: com.android.internal.R.plurals.duration_days_shortest_future,
|
||||
count),
|
||||
count);
|
||||
if (past || count != 1) {
|
||||
mUpdateTimeMillis = computeNextMidnight(timeZone);
|
||||
mUpdateTimeMillis = computeNextMidnight(localNow, zoneId);
|
||||
millisIncrease = -1;
|
||||
} else {
|
||||
millisIncrease = DAY_IN_MILLIS;
|
||||
@@ -311,18 +312,13 @@ public class DateTimeView extends TextView {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timeZone the timezone we are in
|
||||
* @return the timepoint in millis at UTC at midnight in the current timezone
|
||||
* Returns the epoch millis for the next midnight in the specified timezone.
|
||||
*/
|
||||
private long computeNextMidnight(TimeZone timeZone) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(timeZone);
|
||||
c.add(Calendar.DAY_OF_MONTH, 1);
|
||||
c.set(Calendar.HOUR_OF_DAY, 0);
|
||||
c.set(Calendar.MINUTE, 0);
|
||||
c.set(Calendar.SECOND, 0);
|
||||
c.set(Calendar.MILLISECOND, 0);
|
||||
return c.getTimeInMillis();
|
||||
private static long computeNextMidnight(LocalDateTime time, ZoneId zoneId) {
|
||||
// This ignores the chance of overflow: it should never happen.
|
||||
LocalDate tomorrow = time.toLocalDate().plusDays(1);
|
||||
LocalDateTime nextMidnight = LocalDateTime.of(tomorrow, LocalTime.MIDNIGHT);
|
||||
return toEpochMillis(nextMidnight, zoneId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -340,11 +336,10 @@ public class DateTimeView extends TextView {
|
||||
com.android.internal.R.string.now_string_shortest);
|
||||
}
|
||||
|
||||
// Return the date difference for the two times in a given timezone.
|
||||
private static int dayDistance(TimeZone timeZone, long startTime,
|
||||
long endTime) {
|
||||
return getJulianDay(endTime, timeZone.getOffset(endTime) / 1000)
|
||||
- getJulianDay(startTime, timeZone.getOffset(startTime) / 1000);
|
||||
// Return the number of days between the two dates.
|
||||
private static int dayDistance(LocalDateTime start, LocalDateTime end) {
|
||||
return (int) (end.getLong(JulianFields.JULIAN_DAY)
|
||||
- start.getLong(JulianFields.JULIAN_DAY));
|
||||
}
|
||||
|
||||
private DateFormat getTimeFormat() {
|
||||
@@ -389,8 +384,11 @@ public class DateTimeView extends TextView {
|
||||
count);
|
||||
} else if (duration < YEAR_IN_MILLIS) {
|
||||
// In weird cases it can become 0 because of daylight savings
|
||||
TimeZone timeZone = TimeZone.getDefault();
|
||||
count = Math.max(Math.abs(dayDistance(timeZone, mTimeMillis, now)), 1);
|
||||
LocalDateTime localDateTime = mLocalTime;
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
LocalDateTime localNow = toLocalDateTime(now, zoneId);
|
||||
|
||||
count = Math.max(Math.abs(dayDistance(localDateTime, localNow)), 1);
|
||||
result = String.format(getContext().getResources().getQuantityString(past
|
||||
? com.android.internal.
|
||||
R.plurals.duration_days_relative
|
||||
@@ -526,4 +524,17 @@ public class DateTimeView extends TextView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static LocalDateTime toLocalDateTime(long timeMillis, ZoneId zoneId) {
|
||||
// java.time types like LocalDateTime / Instant can support the full range of "long millis"
|
||||
// with room to spare so we do not need to worry about overflow / underflow and the rsulting
|
||||
// exceptions while the input to this class is a long.
|
||||
Instant instant = Instant.ofEpochMilli(timeMillis);
|
||||
return LocalDateTime.ofInstant(instant, zoneId);
|
||||
}
|
||||
|
||||
private static long toEpochMillis(LocalDateTime time, ZoneId zoneId) {
|
||||
Instant instant = time.toInstant(zoneId.getRules().getOffset(time));
|
||||
return instant.toEpochMilli();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user