1c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato/* 2c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * Copyright (C) 2010 The Android Open Source Project 3c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * 4c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 5c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * you may not use this file except in compliance with the License. 6c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * You may obtain a copy of the License at 7c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * 8c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 9c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * 10c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * Unless required by applicable law or agreed to in writing, software 11c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 12c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * See the License for the specific language governing permissions and 14c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * limitations under the License. 15c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato */ 16c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 17c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratopackage android.widget; 18c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 19c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.content.Context; 20c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.content.Intent; 21c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.content.IntentFilter; 22c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.content.BroadcastReceiver; 23c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.database.ContentObserver; 24c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.net.Uri; 25c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.os.Handler; 26c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.text.format.Time; 27c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.util.AttributeSet; 28c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.util.Log; 29c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.provider.Settings; 30c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.provider.Settings.SettingNotFoundException; 31c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.widget.TextView; 32c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport android.widget.RemoteViews.RemoteView; 33c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 34c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport com.android.internal.R; 35c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 36c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport java.text.DateFormat; 37c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport java.text.SimpleDateFormat; 38c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratoimport java.util.Date; 39c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 40c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato// 41c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato// TODO 42c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato// - listen for the next threshold time to update the view. 43c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato// - listen for date format pref changed 44c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato// - put the AM/PM in a smaller font 45c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato// 46c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 47c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato/** 48c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * Displays a given time in a convenient human-readable foramt. 49c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * 50c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato * @hide 51c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato */ 52c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato@RemoteView 53c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onoratopublic class DateTimeView extends TextView { 54c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private static final String TAG = "DateTimeView"; 55c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 56c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private static final long TWELVE_HOURS_IN_MINUTES = 12 * 60; 57c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private static final long TWENTY_FOUR_HOURS_IN_MILLIS = 24 * 60 * 60 * 1000; 58c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 59c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private static final int SHOW_TIME = 0; 60c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private static final int SHOW_MONTH_DAY_YEAR = 1; 61c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 62c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Date mTime; 63c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long mTimeMillis; 64c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 65c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato int mLastDisplay = -1; 66c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato DateFormat mLastFormat; 67c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 68c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private boolean mAttachedToWindow; 69c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private long mUpdateTimeMillis; 70c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 71c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato public DateTimeView(Context context) { 72c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato super(context); 73c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 74c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 75c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato public DateTimeView(Context context, AttributeSet attrs) { 76c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato super(context, attrs); 77c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 78c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 79c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato @Override 80c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato protected void onAttachedToWindow() { 81c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato super.onDetachedFromWindow(); 82c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato registerReceivers(); 83c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mAttachedToWindow = true; 84c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 85c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 86c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato @Override 87c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato protected void onDetachedFromWindow() { 88c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato super.onDetachedFromWindow(); 89c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato unregisterReceivers(); 90c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mAttachedToWindow = false; 91c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 92c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 93c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato @android.view.RemotableViewMethod 94c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato public void setTime(long time) { 95c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Time t = new Time(); 96c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.set(time); 97c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.second = 0; 98c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mTimeMillis = t.toMillis(false); 99c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mTime = new Date(t.year-1900, t.month, t.monthDay, t.hour, t.minute, 0); 100c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato update(); 101c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 102c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 103c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato void update() { 104c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (mTime == null) { 105c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato return; 106c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 107c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 108c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long start = System.nanoTime(); 109c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 110c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato int display; 111c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Date time = mTime; 112c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 113c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Time t = new Time(); 114c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.set(mTimeMillis); 115c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.second = 0; 116c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 117c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.hour -= 12; 118c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long twelveHoursBefore = t.toMillis(false); 119c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.hour += 12; 120c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long twelveHoursAfter = t.toMillis(false); 121c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.hour = 0; 122c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.minute = 0; 123c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long midnightBefore = t.toMillis(false); 124c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.monthDay++; 125c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long midnightAfter = t.toMillis(false); 126c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 127c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long nowMillis = System.currentTimeMillis(); 128c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.set(nowMillis); 129c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato t.second = 0; 130c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato nowMillis = t.normalize(false); 131c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 132c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // Choose the display mode 133c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato choose_display: { 134c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if ((nowMillis >= midnightBefore && nowMillis < midnightAfter) 135c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato || (nowMillis >= twelveHoursBefore && nowMillis < twelveHoursAfter)) { 136c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato display = SHOW_TIME; 137c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato break choose_display; 138c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 139c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // Else, show month day and year. 140c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato display = SHOW_MONTH_DAY_YEAR; 141c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato break choose_display; 142c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 143c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 144c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // Choose the format 145c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato DateFormat format; 146c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (display == mLastDisplay && mLastFormat != null) { 147c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // use cached format 148c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato format = mLastFormat; 149c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } else { 150c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato switch (display) { 151c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato case SHOW_TIME: 152c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato format = getTimeFormat(); 153c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato break; 154c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato case SHOW_MONTH_DAY_YEAR: 155c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato format = getDateFormat(); 156c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato break; 157c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato default: 158c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato throw new RuntimeException("unknown display value: " + display); 159c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 160c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mLastFormat = format; 161c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 162c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 163c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // Set the text 164c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato String text = format.format(mTime); 165c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato setText(text); 166c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 167c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // Schedule the next update 168c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (display == SHOW_TIME) { 169c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // Currently showing the time, update at the later of twelve hours after or midnight. 170c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mUpdateTimeMillis = twelveHoursAfter > midnightAfter ? twelveHoursAfter : midnightAfter; 171c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } else { 172c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // Currently showing the date 173c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (mTimeMillis < nowMillis) { 174c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // If the time is in the past, don't schedule an update 175c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mUpdateTimeMillis = 0; 176c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } else { 177c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // If hte time is in the future, schedule one at the earlier of twelve hours 178c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // before or midnight before. 179c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mUpdateTimeMillis = twelveHoursBefore < midnightBefore 180c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato ? twelveHoursBefore : midnightBefore; 181c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 182c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 183c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (false) { 184c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Log.d(TAG, "update needed for '" + time + "' at '" + new Date(mUpdateTimeMillis) 185c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato + "' - text=" + text); 186c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 187c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 188c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato long finish = System.nanoTime(); 189c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 190c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 191c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private DateFormat getTimeFormat() { 192c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato int res; 193c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Context context = getContext(); 194c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (android.text.format.DateFormat.is24HourFormat(context)) { 195c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato res = R.string.twenty_four_hour_time_format; 196c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } else { 197c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato res = R.string.twelve_hour_time_format; 198c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 199c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato String format = context.getString(res); 200c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato return new SimpleDateFormat(format); 201c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 202c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 203c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private DateFormat getDateFormat() { 204c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato String format = Settings.System.getString(getContext().getContentResolver(), 205c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Settings.System.DATE_FORMAT); 2067747210426f0169b7f10f47a66d15a754b36d64cJoe Onorato if (format == null || "".equals(format)) { 207c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato return DateFormat.getDateInstance(DateFormat.SHORT); 208c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } else { 209f3311c940aee73afb0eeeedde4799e45f544dbc3Adam Powell try { 210f3311c940aee73afb0eeeedde4799e45f544dbc3Adam Powell return new SimpleDateFormat(format); 211f3311c940aee73afb0eeeedde4799e45f544dbc3Adam Powell } catch (IllegalArgumentException e) { 212f3311c940aee73afb0eeeedde4799e45f544dbc3Adam Powell // If we tried to use a bad format string, fall back to a default. 213f3311c940aee73afb0eeeedde4799e45f544dbc3Adam Powell return DateFormat.getDateInstance(DateFormat.SHORT); 214f3311c940aee73afb0eeeedde4799e45f544dbc3Adam Powell } 215c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 216c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 217c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 218c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private void registerReceivers() { 219c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Context context = getContext(); 220c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 221c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato IntentFilter filter = new IntentFilter(); 222c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato filter.addAction(Intent.ACTION_TIME_TICK); 223c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato filter.addAction(Intent.ACTION_TIME_CHANGED); 224c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 225c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 226c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato context.registerReceiver(mBroadcastReceiver, filter); 227c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 228c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT); 229c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato context.getContentResolver().registerContentObserver(uri, true, mContentObserver); 230c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 231c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 232c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private void unregisterReceivers() { 233c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato Context context = getContext(); 234c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato context.unregisterReceiver(mBroadcastReceiver); 235c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato context.getContentResolver().unregisterContentObserver(mContentObserver); 236c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 237c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 238c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 239c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato @Override 240c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato public void onReceive(Context context, Intent intent) { 241c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato String action = intent.getAction(); 242c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (Intent.ACTION_TIME_TICK.equals(action)) { 243c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato if (System.currentTimeMillis() < mUpdateTimeMillis) { 244c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // The update() function takes a few milliseconds to run because of 245c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // all of the time conversions it needs to do, so we can't do that 246c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // every minute. 247c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato return; 248c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 249c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 250c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato // ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format. 251c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mLastFormat = null; 252c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato update(); 253c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 254c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato }; 255c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato 256c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato private ContentObserver mContentObserver = new ContentObserver(new Handler()) { 257c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato @Override 258c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato public void onChange(boolean selfChange) { 259c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato mLastFormat = null; 260c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato update(); 261c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato } 262c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato }; 263c83bb730ec0333e52990a40edf6d54bb66b1d5baJoe Onorato} 264