summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Onorato <joeo@google.com>2010-01-19 16:45:05 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-01-19 16:45:05 -0800
commitfd24feaf796f51866c7354a02d4d8febe255b115 (patch)
tree3a2c43068db20ec61e5b57a1e61df671938ba057
parent290cd9ab8b5f3043e18be665763c914f4d3d7dc5 (diff)
parentc83bb730ec0333e52990a40edf6d54bb66b1d5ba (diff)
downloadframeworks_base-fd24feaf796f51866c7354a02d4d8febe255b115.zip
frameworks_base-fd24feaf796f51866c7354a02d4d8febe255b115.tar.gz
frameworks_base-fd24feaf796f51866c7354a02d4d8febe255b115.tar.bz2
Merge "Add DateTimeView, a widget that shows a time or the date depending on the current time. Use that for notifications instead of a TextView that doesn't ever update."
-rw-r--r--core/java/android/app/Notification.java6
-rw-r--r--core/java/android/widget/DateTimeView.java258
-rw-r--r--core/res/res/layout/status_bar_latest_event_content.xml2
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java21
4 files changed, 281 insertions, 6 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index be5a7d3..4d72f73 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -443,11 +443,7 @@ public class Notification implements Parcelable
contentView.setTextViewText(com.android.internal.R.id.text, contentText);
}
if (this.when != 0) {
- Date date = new Date(when);
- CharSequence str =
- DateUtils.isToday(when) ? DateFormat.getTimeFormat(context).format(date)
- : DateFormat.getDateFormat(context).format(date);
- contentView.setTextViewText(com.android.internal.R.id.time, str);
+ contentView.setLong(com.android.internal.R.id.time, "setTime", when);
}
this.contentView = contentView;
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
new file mode 100644
index 0000000..9067e26
--- /dev/null
+++ b/core/java/android/widget/DateTimeView.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2010 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.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.text.format.Time;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.widget.TextView;
+import android.widget.RemoteViews.RemoteView;
+
+import com.android.internal.R;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+//
+// TODO
+// - listen for the next threshold time to update the view.
+// - listen for date format pref changed
+// - put the AM/PM in a smaller font
+//
+
+/**
+ * Displays a given time in a convenient human-readable foramt.
+ *
+ * @hide
+ */
+@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;
+
+ Date mTime;
+ long mTimeMillis;
+
+ int mLastDisplay = -1;
+ DateFormat mLastFormat;
+
+ private boolean mAttachedToWindow;
+ private long mUpdateTimeMillis;
+
+ public DateTimeView(Context context) {
+ super(context);
+ }
+
+ public DateTimeView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onDetachedFromWindow();
+ registerReceivers();
+ mAttachedToWindow = true;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ unregisterReceivers();
+ mAttachedToWindow = false;
+ }
+
+ @android.view.RemotableViewMethod
+ public void setTime(long time) {
+ Time t = new Time();
+ t.set(time);
+ t.second = 0;
+ mTimeMillis = t.toMillis(false);
+ mTime = new Date(t.year-1900, t.month, t.monthDay, t.hour, t.minute, 0);
+ update();
+ }
+
+ void update() {
+ if (mTime == null) {
+ return;
+ }
+
+ long start = System.nanoTime();
+
+ int display;
+ Date time = mTime;
+
+ Time t = new Time();
+ t.set(mTimeMillis);
+ t.second = 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);
+
+ // Choose the display mode
+ choose_display: {
+ if ((nowMillis >= midnightBefore && nowMillis < midnightAfter)
+ || (nowMillis >= twelveHoursBefore && nowMillis < twelveHoursAfter)) {
+ display = SHOW_TIME;
+ break choose_display;
+ }
+ // Else, show month day and year.
+ display = SHOW_MONTH_DAY_YEAR;
+ break choose_display;
+ }
+
+ // Choose the format
+ DateFormat format;
+ if (display == mLastDisplay && mLastFormat != null) {
+ // use cached format
+ format = mLastFormat;
+ } else {
+ switch (display) {
+ case SHOW_TIME:
+ format = getTimeFormat();
+ break;
+ case SHOW_MONTH_DAY_YEAR:
+ format = getDateFormat();
+ break;
+ default:
+ throw new RuntimeException("unknown display value: " + display);
+ }
+ mLastFormat = format;
+ }
+
+ // Set the text
+ String text = format.format(mTime);
+ setText(text);
+
+ // Schedule the next update
+ if (display == SHOW_TIME) {
+ // Currently showing the time, update at the later of twelve hours after or midnight.
+ mUpdateTimeMillis = twelveHoursAfter > midnightAfter ? twelveHoursAfter : midnightAfter;
+ } else {
+ // Currently showing the date
+ if (mTimeMillis < nowMillis) {
+ // If the time is in the past, don't schedule an update
+ mUpdateTimeMillis = 0;
+ } else {
+ // If hte time is in the future, schedule one at the earlier of twelve hours
+ // before or midnight before.
+ mUpdateTimeMillis = twelveHoursBefore < midnightBefore
+ ? twelveHoursBefore : midnightBefore;
+ }
+ }
+ if (false) {
+ Log.d(TAG, "update needed for '" + time + "' at '" + new Date(mUpdateTimeMillis)
+ + "' - text=" + text);
+ }
+
+ long finish = System.nanoTime();
+ }
+
+ private DateFormat getTimeFormat() {
+ int res;
+ Context context = getContext();
+ if (android.text.format.DateFormat.is24HourFormat(context)) {
+ res = R.string.twenty_four_hour_time_format;
+ } else {
+ res = R.string.twelve_hour_time_format;
+ }
+ String format = context.getString(res);
+ return new SimpleDateFormat(format);
+ }
+
+ private DateFormat getDateFormat() {
+ String format = Settings.System.getString(getContext().getContentResolver(),
+ Settings.System.DATE_FORMAT);
+ if ("".equals(format)) {
+ return DateFormat.getDateInstance(DateFormat.SHORT);
+ } else {
+ return new SimpleDateFormat(format);
+ }
+ }
+
+ private void registerReceivers() {
+ Context context = getContext();
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_TIME_TICK);
+ filter.addAction(Intent.ACTION_TIME_CHANGED);
+ filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+ context.registerReceiver(mBroadcastReceiver, filter);
+
+ Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT);
+ context.getContentResolver().registerContentObserver(uri, true, mContentObserver);
+ }
+
+ private void unregisterReceivers() {
+ Context context = getContext();
+ context.unregisterReceiver(mBroadcastReceiver);
+ context.getContentResolver().unregisterContentObserver(mContentObserver);
+ }
+
+ private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_TIME_TICK.equals(action)) {
+ if (System.currentTimeMillis() < mUpdateTimeMillis) {
+ // The update() function takes a few milliseconds to run because of
+ // all of the time conversions it needs to do, so we can't do that
+ // every minute.
+ return;
+ }
+ }
+ // ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format.
+ mLastFormat = null;
+ update();
+ }
+ };
+
+ private ContentObserver mContentObserver = new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mLastFormat = null;
+ update();
+ }
+ };
+}
diff --git a/core/res/res/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml
index 2f7036f..c3aa041 100644
--- a/core/res/res/layout/status_bar_latest_event_content.xml
+++ b/core/res/res/layout/status_bar_latest_event_content.xml
@@ -45,7 +45,7 @@
android:textSize="14sp"
android:paddingLeft="4dp"
/>
- <TextView android:id="@+id/time"
+ <android.widget.DateTimeView android:id="@+id/time"
android:layout_marginLeft="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index f2ddd0f..ffc2cbc 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -121,6 +121,20 @@ public class NotificationTestList extends TestActivity
}
},
+ new Test("Times") {
+ public void run()
+ {
+ long now = System.currentTimeMillis();
+
+ timeNotification(7, "24 hours from now", now+(1000*60*60*24));
+ timeNotification(6, "12:01:00 from now", now+(1000*60*60*12)+(60*1000));
+ timeNotification(5, "12 hours from now", now+(1000*60*60*12));
+ timeNotification(4, "now", now);
+ timeNotification(3, "11:59:00 ago", now-((1000*60*60*12)-(60*1000)));
+ timeNotification(2, "12 hours ago", now-(1000*60*60*12));
+ timeNotification(1, "24 hours ago", now-(1000*60*60*24));
+ }
+ },
new StateStress("Stress - Ongoing / Latest", 100, 100, new Runnable[] {
new Runnable() {
public void run() {
@@ -590,5 +604,12 @@ public class NotificationTestList extends TestActivity
mHandler.postDelayed(mRunnable, mPause);
}
}
+
+ void timeNotification(int n, String label, long time) {
+ mNM.notify(n, new Notification(NotificationTestList.this,
+ R.drawable.ic_statusbar_missedcall, null,
+ time, label, "" + new java.util.Date(time), null));
+
+ }
}