diff options
Diffstat (limited to 'packages/StatusBarPhone')
-rw-r--r-- | packages/StatusBarPhone/res/layout/status_bar.xml | 11 | ||||
-rw-r--r-- | packages/StatusBarPhone/src/com/android/policy/statusbar/phone/Clock.java | 192 |
2 files changed, 203 insertions, 0 deletions
diff --git a/packages/StatusBarPhone/res/layout/status_bar.xml b/packages/StatusBarPhone/res/layout/status_bar.xml index 418d383..2a00274 100644 --- a/packages/StatusBarPhone/res/layout/status_bar.xml +++ b/packages/StatusBarPhone/res/layout/status_bar.xml @@ -47,6 +47,17 @@ android:paddingRight="6dip" android:gravity="center_vertical" android:orientation="horizontal"/> + + <com.android.policy.statusbar.phone.Clock + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:singleLine="true" + android:paddingRight="6dip" + android:textSize="16sp" + android:textStyle="bold" + android:gravity="center_vertical|left" + android:textColor="?android:attr/textColorPrimaryInverse" + /> </LinearLayout> <LinearLayout android:id="@+id/ticker" diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/Clock.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/Clock.java new file mode 100644 index 0000000..8ad1fb6 --- /dev/null +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/Clock.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2006 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 com.android.policy.statusbar.phone; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.BroadcastReceiver; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.text.format.DateFormat; +import android.text.style.RelativeSizeSpan; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; + +import com.android.internal.R; + +/** + * This widget display an analogic clock with two hands for hours and + * minutes. + */ +public class Clock extends TextView { + private final Handler mHandler = new Handler(); + private boolean mAttached; + private Calendar mCalendar; + private String mClockFormatString; + private SimpleDateFormat mClockFormat; + + public Clock(Context context) { + this(context, null); + } + + public Clock(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public Clock(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + if (!mAttached) { + mAttached = true; + IntentFilter filter = new IntentFilter(); + + filter.addAction(Intent.ACTION_TIME_TICK); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); + + getContext().registerReceiver(mIntentReceiver, filter, null, mHandler); + } + + // NOTE: It's safe to do these after registering the receiver since the receiver always runs + // 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 = Calendar.getInstance(TimeZone.getDefault()); + + // Make sure we update to the current time + updateClock(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mAttached) { + getContext().unregisterReceiver(mIntentReceiver); + mAttached = false; + } + } + + private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) { + String tz = intent.getStringExtra("time-zone"); + mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz)); + if (mClockFormat != null) { + mClockFormat.setTimeZone(mCalendar.getTimeZone()); + } + } + updateClock(); + } + }; + + final void updateClock() { + mCalendar.setTimeInMillis(System.currentTimeMillis()); + setText(getSmallTime()); + } + + private final CharSequence getSmallTime() { + Context context = getContext(); + boolean b24 = DateFormat.is24HourFormat(context); + int res; + + if (b24) { + res = R.string.twenty_four_hour_time_format; + } else { + res = R.string.twelve_hour_time_format; + } + + final char MAGIC1 = '\uEF00'; + final char MAGIC2 = '\uEF01'; + + SimpleDateFormat sdf; + String format = context.getString(res); + if (!format.equals(mClockFormatString)) { + /* + * Search for an unquoted "a" in the format string, so we can + * add dummy characters around it to let us find it again after + * formatting and change its size. + */ + int a = -1; + boolean quoted = false; + for (int i = 0; i < format.length(); i++) { + char c = format.charAt(i); + + if (c == '\'') { + quoted = !quoted; + } + + if (!quoted && c == 'a') { + a = i; + break; + } + } + + if (a >= 0) { + // Move a back so any whitespace before the AM/PM is also in the alternate size. + final int b = a; + while (a > 0 && Character.isWhitespace(format.charAt(a-1))) { + a--; + } + format = format.substring(0, a) + MAGIC1 + format.substring(a, b) + + "a" + MAGIC2 + format.substring(b + 1); + } + + mClockFormat = sdf = new SimpleDateFormat(format); + mClockFormatString = format; + } else { + sdf = mClockFormat; + } + String result = sdf.format(mCalendar.getTime()); + + int magic1 = result.indexOf(MAGIC1); + int magic2 = result.indexOf(MAGIC2); + + if (magic1 >= 0 && magic2 > magic1) { + SpannableStringBuilder formatted = new SpannableStringBuilder(result); + + formatted.setSpan(new RelativeSizeSpan(0.7f), magic1, magic2, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + + formatted.delete(magic2, magic2 + 1); + formatted.delete(magic1, magic1 + 1); + + return formatted; + } else { + return result; + } + } +} + |