/* * Copyright (C) 2014 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.systemui.statusbar.policy; import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.UserHandle; import android.text.format.DateFormat; import android.util.AttributeSet; import android.widget.LinearLayout; import android.widget.TextClock; import com.android.systemui.R; /** * Container for a clock which has two separate views for the clock itself and AM/PM indicator. This * is used to scale the clock independently of AM/PM. */ public class SplitClockView extends LinearLayout { private TextClock mTimeView; private TextClock mAmPmView; private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_TIME_CHANGED.equals(action) || Intent.ACTION_TIMEZONE_CHANGED.equals(action) || Intent.ACTION_LOCALE_CHANGED.equals(action) || Intent.ACTION_CONFIGURATION_CHANGED.equals(action) || Intent.ACTION_USER_SWITCHED.equals(action)) { updatePatterns(); } } }; public SplitClockView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); mTimeView = findViewById(R.id.time_view); mAmPmView = findViewById(R.id.am_pm_view); mTimeView.setShowCurrentUserTime(true); mAmPmView.setShowCurrentUserTime(true); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); filter.addAction(Intent.ACTION_LOCALE_CHANGED); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(Intent.ACTION_USER_SWITCHED); getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null); updatePatterns(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getContext().unregisterReceiver(mIntentReceiver); } private void updatePatterns() { String formatString = DateFormat.getTimeFormatString(getContext(), ActivityManager.getCurrentUser()); int index = getAmPmPartEndIndex(formatString); String timeString; String amPmString; if (index == -1) { timeString = formatString; amPmString = ""; } else { timeString = formatString.substring(0, index); amPmString = formatString.substring(index); } mTimeView.setFormat12Hour(timeString); mTimeView.setFormat24Hour(timeString); mTimeView.setContentDescriptionFormat12Hour(formatString); mTimeView.setContentDescriptionFormat24Hour(formatString); mAmPmView.setFormat12Hour(amPmString); mAmPmView.setFormat24Hour(amPmString); } /** * @return the index where the AM/PM part starts at the end in {@code formatString} including * leading white spaces or {@code -1} if no AM/PM part is found or {@code formatString} * doesn't end with AM/PM part */ private static int getAmPmPartEndIndex(String formatString) { boolean hasAmPm = false; int length = formatString.length(); for (int i = length - 1; i >= 0; i--) { char c = formatString.charAt(i); boolean isAmPm = c == 'a'; boolean isWhitespace = Character.isWhitespace(c); if (isAmPm) { hasAmPm = true; } if (isAmPm || isWhitespace) { continue; } if (i == length - 1) { // First character was not AM/PM and not whitespace, so it's not ending with AM/PM. return -1; } else { // If we have AM/PM at all, return last index, or -1 to indicate that it's not // ending with AM/PM. return hasAmPm ? i + 1 : -1; } } // Only AM/PM and whitespaces? The whole string is AM/PM. Else: Only whitespaces in the // string. return hasAmPm ? 0 : -1; } }