From 36d570863aad37c949e578ca7a8e45abfd36d5c8 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Tue, 19 Apr 2016 18:31:47 -0700 Subject: [PATCH] Switched the notification time to relative time The time is now displayed in a relative manner instead of absolute. Change-Id: Idcc4411ed07991b6e176c4890a0d804394d8598a Fixes: 27435284 --- core/java/android/widget/DateTimeView.java | 155 ++++++++++++++++-- .../notification_template_part_time.xml | 1 + core/res/res/values/attrs.xml | 4 + core/res/res/values/strings.xml | 43 +++++ core/res/res/values/symbols.xml | 11 ++ 5 files changed, 199 insertions(+), 15 deletions(-) diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index d20b9244a4b2b..39eba7d3d7063 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -16,21 +16,32 @@ package android.widget; +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.app.ActivityThread; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.BroadcastReceiver; +import android.content.res.Configuration; +import android.content.res.TypedArray; import android.database.ContentObserver; +import android.icu.util.Calendar; import android.os.Handler; import android.text.format.Time; import android.util.AttributeSet; -import android.util.Log; import android.widget.RemoteViews.RemoteView; +import com.android.internal.R; + import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.TimeZone; // // TODO @@ -46,11 +57,6 @@ import java.util.Date; */ @RemoteView public class DateTimeView extends TextView { - private static final String TAG = "DateTimeView"; - - private static final long TWELVE_HOURS_IN_MINUTES = 12 * 60; - private static final long TWENTY_FOUR_HOURS_IN_MILLIS = 24 * 60 * 60 * 1000; - private static final int SHOW_TIME = 0; private static final int SHOW_MONTH_DAY_YEAR = 1; @@ -62,13 +68,30 @@ public class DateTimeView extends TextView { private long mUpdateTimeMillis; private static final ThreadLocal sReceiverInfo = new ThreadLocal(); + private String mNowText; + private boolean mShowRelativeTime; public DateTimeView(Context context) { - super(context); + this(context, null); } public DateTimeView(Context context, AttributeSet attrs) { super(context, attrs); + final TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.DateTimeView, 0, + 0); + + final int N = a.getIndexCount(); + for (int i = 0; i < N; i++) { + int attr = a.getIndex(i); + switch (attr) { + case R.styleable.DateTimeView_showRelative: + boolean relative = a.getBoolean(i, false); + setShowRelativeTime(relative); + break; + } + } + a.recycle(); } @Override @@ -101,12 +124,21 @@ public class DateTimeView extends TextView { update(); } + @android.view.RemotableViewMethod + public void setShowRelativeTime(boolean showRelativeTime) { + mShowRelativeTime = showRelativeTime; + updateNowText(); + update(); + } + void update() { if (mTime == null) { return; } - - long start = System.nanoTime(); + if (mShowRelativeTime) { + updateRelativeTime(); + return; + } int display; Date time = mTime; @@ -181,12 +213,105 @@ public class DateTimeView extends TextView { ? twelveHoursBefore : midnightBefore; } } - if (false) { - Log.d(TAG, "update needed for '" + time + "' at '" + new Date(mUpdateTimeMillis) - + "' - text=" + text); - } + } - long finish = System.nanoTime(); + private void updateRelativeTime() { + long now = System.currentTimeMillis(); + long duration = Math.abs(now - mTimeMillis); + int count; + long millisIncrease; + boolean past = (now >= mTimeMillis); + String result; + if (duration < MINUTE_IN_MILLIS) { + setText(mNowText); + mUpdateTimeMillis = mTimeMillis + MINUTE_IN_MILLIS + 1; + return; + } else if (duration < HOUR_IN_MILLIS) { + count = (int)(duration / MINUTE_IN_MILLIS); + result = String.format(getContext().getResources().getQuantityString(past + ? com.android.internal.R.plurals.duration_minutes_shortest + : com.android.internal.R.plurals.duration_minutes_shortest_future, + count), + count); + millisIncrease = MINUTE_IN_MILLIS; + } else if (duration < DAY_IN_MILLIS) { + count = (int)(duration / HOUR_IN_MILLIS); + result = String.format(getContext().getResources().getQuantityString(past + ? com.android.internal.R.plurals.duration_hours_shortest + : com.android.internal.R.plurals.duration_hours_shortest_future, + count), + count); + 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); + 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); + millisIncrease = -1; + } else { + millisIncrease = DAY_IN_MILLIS; + } + + } else { + count = (int)(duration / YEAR_IN_MILLIS); + result = String.format(getContext().getResources().getQuantityString(past + ? com.android.internal.R.plurals.duration_years_shortest + : com.android.internal.R.plurals.duration_years_shortest_future, + count), + count); + millisIncrease = YEAR_IN_MILLIS; + } + if (millisIncrease != -1) { + if (past) { + mUpdateTimeMillis = mTimeMillis + millisIncrease * (count + 1) + 1; + } else { + mUpdateTimeMillis = mTimeMillis - millisIncrease * count + 1; + } + } + setText(result); + } + + /** + * @param timeZone the timezone we are in + * @return the timepoint in millis at UTC at midnight in the current timezone + */ + private long computeNextMidnight(TimeZone timeZone) { + Calendar c = Calendar.getInstance(); + c.setTimeZone(libcore.icu.DateUtilsBridge.icuTimeZone(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(); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + updateNowText(); + update(); + } + + private void updateNowText() { + if (!mShowRelativeTime) { + return; + } + mNowText = getContext().getResources().getString( + 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); } private DateFormat getTimeFormat() { diff --git a/core/res/res/layout/notification_template_part_time.xml b/core/res/res/layout/notification_template_part_time.xml index 442ff8cef4435..e53f37807df9e 100644 --- a/core/res/res/layout/notification_template_part_time.xml +++ b/core/res/res/layout/notification_template_part_time.xml @@ -21,5 +21,6 @@ android:layout_gravity="center" android:layout_marginEnd="4dp" android:layout_weight="0" + android:showRelative="true" android:singleLine="true" /> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 85e0b88bd9375..8c47ba2f2f35e 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -8134,6 +8134,10 @@ i + + + + diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 6776d3b71b35c..9cd229e78641a 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2423,6 +2423,49 @@ %d hours + + now + + + + %dm + + + + + %dh + + + + + %dd + + + + + %dy + + + + + in %dm + + + + + in %dh + + + + + in %dd + + + + + in %dy + + Video problem diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 60060a3702053..adeaa63900b6b 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2508,6 +2508,17 @@ + + + + + + + + + + +