1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.policy; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.res.TypedArray; 24 import android.icu.text.DateFormat; 25 import android.icu.text.DisplayContext; 26 import android.text.TextUtils; 27 import android.util.AttributeSet; 28 import android.widget.TextView; 29 30 import com.android.systemui.Dependency; 31 import com.android.systemui.R; 32 33 import java.util.Date; 34 import java.util.Locale; 35 36 public class DateView extends TextView { 37 private static final String TAG = "DateView"; 38 39 private final Date mCurrentTime = new Date(); 40 41 private DateFormat mDateFormat; 42 private String mLastText; 43 private String mDatePattern; 44 45 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 46 @Override 47 public void onReceive(Context context, Intent intent) { 48 final String action = intent.getAction(); 49 if (Intent.ACTION_TIME_TICK.equals(action) 50 || Intent.ACTION_TIME_CHANGED.equals(action) 51 || Intent.ACTION_TIMEZONE_CHANGED.equals(action) 52 || Intent.ACTION_LOCALE_CHANGED.equals(action)) { 53 if (Intent.ACTION_LOCALE_CHANGED.equals(action) 54 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { 55 // need to get a fresh date format 56 getHandler().post(() -> mDateFormat = null); 57 } 58 getHandler().post(() -> updateClock()); 59 } 60 } 61 }; 62 DateView(Context context, AttributeSet attrs)63 public DateView(Context context, AttributeSet attrs) { 64 super(context, attrs); 65 TypedArray a = context.getTheme().obtainStyledAttributes( 66 attrs, 67 R.styleable.DateView, 68 0, 0); 69 70 try { 71 mDatePattern = a.getString(R.styleable.DateView_datePattern); 72 } finally { 73 a.recycle(); 74 } 75 if (mDatePattern == null) { 76 mDatePattern = getContext().getString(R.string.system_ui_date_pattern); 77 } 78 } 79 80 @Override onAttachedToWindow()81 protected void onAttachedToWindow() { 82 super.onAttachedToWindow(); 83 84 IntentFilter filter = new IntentFilter(); 85 filter.addAction(Intent.ACTION_TIME_TICK); 86 filter.addAction(Intent.ACTION_TIME_CHANGED); 87 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 88 filter.addAction(Intent.ACTION_LOCALE_CHANGED); 89 getContext().registerReceiver(mIntentReceiver, filter, null, 90 Dependency.get(Dependency.TIME_TICK_HANDLER)); 91 92 updateClock(); 93 } 94 95 @Override onDetachedFromWindow()96 protected void onDetachedFromWindow() { 97 super.onDetachedFromWindow(); 98 99 mDateFormat = null; // reload the locale next time 100 getContext().unregisterReceiver(mIntentReceiver); 101 } 102 updateClock()103 protected void updateClock() { 104 if (mDateFormat == null) { 105 final Locale l = Locale.getDefault(); 106 DateFormat format = DateFormat.getInstanceForSkeleton(mDatePattern, l); 107 format.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE); 108 mDateFormat = format; 109 } 110 111 mCurrentTime.setTime(System.currentTimeMillis()); 112 113 final String text = mDateFormat.format(mCurrentTime); 114 if (!text.equals(mLastText)) { 115 setText(text); 116 mLastText = text; 117 } 118 } 119 setDatePattern(String pattern)120 public void setDatePattern(String pattern) { 121 if (TextUtils.equals(pattern, mDatePattern)) { 122 return; 123 } 124 mDatePattern = pattern; 125 mDateFormat = null; 126 if (isAttachedToWindow()) { 127 updateClock(); 128 } 129 } 130 } 131