diff options
author | Matt Booth <kryten2k35@gmail.com> | 2013-09-05 13:27:35 +0200 |
---|---|---|
committer | DvTonder <david.vantonder@gmail.com> | 2013-09-25 18:16:49 -0400 |
commit | 76dae0662a9b70a7b560510e75db02484a0383e3 (patch) | |
tree | 5d32816f0e57f03ec6a6a02d166d553205151840 /src | |
parent | f6ad8fa95524e4b955e308efc9871df50237bd64 (diff) | |
download | packages_apps_LockClock-76dae0662a9b70a7b560510e75db02484a0383e3.zip packages_apps_LockClock-76dae0662a9b70a7b560510e75db02484a0383e3.tar.gz packages_apps_LockClock-76dae0662a9b70a7b560510e75db02484a0383e3.tar.bz2 |
LockClock: Add support for API level 16
Thanks to Matt Booth for the main implementation and Danny Baumann
for the initial porting into the CM source tree
Change-Id: I3de1e786c80ee440a4685da3d6c7b3dd989fd8e3
Diffstat (limited to 'src')
8 files changed, 220 insertions, 8 deletions
diff --git a/src/com/cyanogenmod/lockclock/ClockWidgetProvider.java b/src/com/cyanogenmod/lockclock/ClockWidgetProvider.java index 0c0beb5..30c1bda 100644 --- a/src/com/cyanogenmod/lockclock/ClockWidgetProvider.java +++ b/src/com/cyanogenmod/lockclock/ClockWidgetProvider.java @@ -22,8 +22,12 @@ import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.util.Log; + import com.cyanogenmod.lockclock.misc.Constants; +import com.cyanogenmod.lockclock.misc.WidgetUtils; import com.cyanogenmod.lockclock.weather.WeatherUpdateService; +import com.cyanogenmod.lockclock.ClockWidgetService; +import com.cyanogenmod.lockclock.WidgetApplication; public class ClockWidgetProvider extends AppWidgetProvider { private static final String TAG = "ClockWidgetProvider"; @@ -72,7 +76,7 @@ public class ClockWidgetProvider extends AppWidgetProvider { || Intent.ACTION_TIMEZONE_CHANGED.equals(action) || Intent.ACTION_DATE_CHANGED.equals(action) || Intent.ACTION_LOCALE_CHANGED.equals(action) - || Intent.ACTION_ALARM_CHANGED.equals(action) + || "android.intent.action.ALARM_CHANGED".equals(action) || ClockWidgetService.ACTION_REFRESH_CALENDAR.equals(action)) { updateWidgets(context, true, false); @@ -112,6 +116,14 @@ public class ClockWidgetProvider extends AppWidgetProvider { public void onEnabled(Context context) { if (D) Log.d(TAG, "Scheduling next weather update"); WeatherUpdateService.scheduleNextUpdate(context); + + // Start the broadcast receiver (API 16 devices) + // This will schedule a repeating alarm every minute to handle the clock refresh + // Once triggered, the receiver will unregister itself when its work is done + if (!WidgetUtils.isTextClockAvailable()) { + final WidgetApplication app = (WidgetApplication) context.getApplicationContext(); + app.startTickReceiver(); + } } @Override @@ -119,5 +131,10 @@ public class ClockWidgetProvider extends AppWidgetProvider { if (D) Log.d(TAG, "Cleaning up: Clearing all pending alarms"); ClockWidgetService.cancelUpdates(context); WeatherUpdateService.cancelUpdates(context); + + // Stop the clock update event (API 16 devices) + if (!WidgetUtils.isTextClockAvailable()) { + WidgetApplication.cancelClockRefresh(context); + } } } diff --git a/src/com/cyanogenmod/lockclock/ClockWidgetService.java b/src/com/cyanogenmod/lockclock/ClockWidgetService.java index 381e3d4..53b8baa 100755 --- a/src/com/cyanogenmod/lockclock/ClockWidgetService.java +++ b/src/com/cyanogenmod/lockclock/ClockWidgetService.java @@ -39,6 +39,8 @@ import com.cyanogenmod.lockclock.misc.Preferences; import com.cyanogenmod.lockclock.misc.WidgetUtils; import com.cyanogenmod.lockclock.weather.WeatherInfo; import com.cyanogenmod.lockclock.weather.WeatherUpdateService; + +import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -129,6 +131,11 @@ public class ClockWidgetService extends IntentService { refreshClock(remoteViews, smallWidget, digitalClock); refreshAlarmStatus(remoteViews, smallWidget); + // Refresh the time if using TextView Clock (API 16) + if(!WidgetUtils.isTextClockAvailable()) { + refreshTime(remoteViews, smallWidget); + } + // Don't bother with Calendar if its not visible if (showCalendar) { refreshCalendar(remoteViews, id); @@ -167,7 +174,7 @@ public class ClockWidgetService extends IntentService { // Analog or Digital clock if (digitalClock) { // Hours/Minutes is specific to Digital, set it's size - refreshClockFont(clockViews); + refreshClockFont(clockViews, smallWidget); clockViews.setViewVisibility(R.id.digital_clock, View.VISIBLE); clockViews.setViewVisibility(R.id.analog_clock, View.GONE); } else { @@ -186,8 +193,45 @@ public class ClockWidgetService extends IntentService { } } - private void refreshClockFont(RemoteViews clockViews) { + // API 16 TextView Clock support + private void refreshTime(RemoteViews clockViews, boolean smallWidget) { + Locale locale = Locale.getDefault(); + Date now = new Date(); + String dateFormat = getString(R.string.abbrev_wday_month_day_no_year); + CharSequence date = DateFormat.format(dateFormat, now); + String hours = new SimpleDateFormat(getHourFormat(), locale).format(now); + String minutes = new SimpleDateFormat(getString(R.string.widget_12_hours_format_no_ampm_m), + locale).format(now); + + // Hours + if (Preferences.useBoldFontForHours(this)) { + clockViews.setTextViewText(R.id.clock1_bold, hours); + } else { + clockViews.setTextViewText(R.id.clock1_regular, hours); + } + + // Minutes + if (Preferences.useBoldFontForMinutes(this)) { + clockViews.setTextViewText(R.id.clock2_bold, minutes); + } else { + clockViews.setTextViewText(R.id.clock2_regular, minutes); + } + + // Date and Alarm font + if (!smallWidget) { + if (Preferences.useBoldFontForDateAndAlarms(this)) { + clockViews.setTextViewText(R.id.date_bold, date); + } else { + clockViews.setTextViewText(R.id.date_regular, date); + } + } else { + clockViews.setTextViewText(R.id.date, date); + } + } + + private void refreshClockFont(RemoteViews clockViews, boolean smallWidget) { int color = Preferences.clockFontColor(this); + String amPM = new SimpleDateFormat("a", Locale.getDefault()).format(new Date()); // Hours if (Preferences.useBoldFontForHours(this)) { @@ -210,6 +254,15 @@ public class ClockWidgetService extends IntentService { clockViews.setViewVisibility(R.id.clock2_bold, View.GONE); clockViews.setTextColor(R.id.clock2_regular, color); } + + // Show the AM/PM indicator + if (!DateFormat.is24HourFormat(this) && Preferences.showAmPmIndicator(this)) { + clockViews.setViewVisibility(R.id.clock_ampm, View.VISIBLE); + clockViews.setTextViewText(R.id.clock_ampm, amPM); + clockViews.setTextColor(R.id.clock_ampm, color); + } else { + clockViews.setViewVisibility(R.id.clock_ampm, View.GONE); + } } private void refreshDateAlarmFont(RemoteViews clockViews, boolean smallWidget) { @@ -243,6 +296,16 @@ public class ClockWidgetService extends IntentService { clockViews.setTextViewTextSize(R.id.clock2_regular, TypedValue.COMPLEX_UNIT_PX, fontSize * scale); } + private String getHourFormat() { + String format; + if (DateFormat.is24HourFormat(this)) { + format = getString(R.string.widget_24_hours_format_h); + } else { + format = getString(R.string.widget_12_hours_format_h); + } + return format; + } + //=============================================================================================== // Alarm related functionality //=============================================================================================== @@ -260,18 +323,21 @@ public class ClockWidgetService extends IntentService { if (!smallWidget) { if (Preferences.useBoldFontForDateAndAlarms(this)) { - alarmViews.setTextViewText(R.id.nextAlarm_bold, nextAlarm.toString().toUpperCase(Locale.getDefault())); + alarmViews.setTextViewText(R.id.nextAlarm_bold, + nextAlarm.toString().toUpperCase(Locale.getDefault())); alarmViews.setViewVisibility(R.id.nextAlarm_bold, View.VISIBLE); alarmViews.setViewVisibility(R.id.nextAlarm_regular, View.GONE); alarmViews.setTextColor(R.id.nextAlarm_bold, color); } else { - alarmViews.setTextViewText(R.id.nextAlarm_regular, nextAlarm.toString().toUpperCase(Locale.getDefault())); + alarmViews.setTextViewText(R.id.nextAlarm_regular, + nextAlarm.toString().toUpperCase(Locale.getDefault())); alarmViews.setViewVisibility(R.id.nextAlarm_regular, View.VISIBLE); alarmViews.setViewVisibility(R.id.nextAlarm_bold, View.GONE); alarmViews.setTextColor(R.id.nextAlarm_regular, color); } } else { - alarmViews.setTextViewText(R.id.nextAlarm, nextAlarm.toString().toUpperCase(Locale.getDefault())); + alarmViews.setTextViewText(R.id.nextAlarm, + nextAlarm.toString().toUpperCase(Locale.getDefault())); alarmViews.setViewVisibility(R.id.nextAlarm, View.VISIBLE); alarmViews.setTextColor(R.id.nextAlarm, color); } @@ -424,7 +490,7 @@ public class ClockWidgetService extends IntentService { // Register an onClickListener on Calendar starting the Calendar app final Intent calendarClickIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_CALENDAR); - final PendingIntent calendarClickPendingIntent = PendingIntent.getActivity(this, 0, calendarClickIntent, PendingIntent.FLAG_UPDATE_CURRENT); + final PendingIntent calendarClickPendingIntent = PendingIntent.getActivity(this, 0, calendarClickIntent,PendingIntent.FLAG_UPDATE_CURRENT); calendarViews.setOnClickPendingIntent(R.id.calendar_icon, calendarClickPendingIntent); final Intent eventClickIntent = new Intent(Intent.ACTION_VIEW); diff --git a/src/com/cyanogenmod/lockclock/WidgetApplication.java b/src/com/cyanogenmod/lockclock/WidgetApplication.java new file mode 100644 index 0000000..c805f5c --- /dev/null +++ b/src/com/cyanogenmod/lockclock/WidgetApplication.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project (DvTonder) + * + * 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.cyanogenmod.lockclock; + +import com.cyanogenmod.lockclock.misc.Constants; +import com.cyanogenmod.lockclock.ClockWidgetProvider; +import com.cyanogenmod.lockclock.ClockWidgetService; + +import android.app.AlarmManager; +import android.app.Application; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.util.Log; + +public class WidgetApplication extends Application { + private static final String TAG = "WidgetApplication"; + private static boolean D = Constants.DEBUG; + private static final long INTERVAL_ONE_MINUTE = 60000L; + + private BroadcastReceiver mTickReceiver = null; + + /** + * BroadReceiver and supporting functions used for handling clock ticks + * for the TextView clock support (API 16) by scheduling a repeating + * alarm event every 60 seconds and triggering a refresh of the widget + */ + public class TickReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_TIME_TICK.equals(action)){ + if (D) Log.d(TAG, "Clock tick event received"); + + // Schedule the clock refresh alarm event + scheduleClockRefresh(context); + + // Refresh the widget + Intent refreshIntent = new Intent(context, ClockWidgetProvider.class); + refreshIntent.setAction(ClockWidgetService.ACTION_REFRESH); + context.sendBroadcast(refreshIntent); + + // We no longer need the tick receiver, its done its job, stop it + stopTickReceiver(); + } + } + } + + public void startTickReceiver() { + // Clean up first, just in case + stopTickReceiver(); + + // Start the new receiver + if (D) Log.d(TAG, "Registering clock tick receiver"); + mTickReceiver = new TickReceiver(); + registerReceiver(mTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK)); + } + + public void stopTickReceiver() { + if (mTickReceiver != null) { + if (D) Log.d(TAG, "Cleaning up: Unregistering clock tick receiver"); + unregisterReceiver(mTickReceiver); + mTickReceiver = null; + } + } + + private static void scheduleClockRefresh(Context context) { + if (D) Log.d(TAG, "Starting clock refresh alarm"); + AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + long due = System.currentTimeMillis() + INTERVAL_ONE_MINUTE; + am.setRepeating(AlarmManager.RTC, due, INTERVAL_ONE_MINUTE, getClockRefreshIntent(context)); + } + + public static void cancelClockRefresh(Context context) { + if (D) Log.d(TAG, "Cleaning up: Stopping clock refresh alarm"); + AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + am.cancel(getClockRefreshIntent(context)); + } + + private static PendingIntent getClockRefreshIntent(Context context) { + Intent i = new Intent(context, ClockWidgetService.class); + i.setAction(ClockWidgetService.ACTION_REFRESH); + return PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT); + } +} diff --git a/src/com/cyanogenmod/lockclock/calendar/CalendarWidgetService.java b/src/com/cyanogenmod/lockclock/calendar/CalendarWidgetService.java index 6745fa1..6127924 100755 --- a/src/com/cyanogenmod/lockclock/calendar/CalendarWidgetService.java +++ b/src/com/cyanogenmod/lockclock/calendar/CalendarWidgetService.java @@ -261,7 +261,7 @@ class CalendarRemoteViewsFactory implements RemoteViewsFactory { // all day events are stored in UTC, that is why we need to fetch events after 'later' Uri uri = Uri.withAppendedPath(CalendarContract.Instances.CONTENT_URI, String.format("%d/%d", now - DAY_IN_MILLIS, later + DAY_IN_MILLIS)); - Cursor cursor = cursor = context.getContentResolver().query(uri, projection, + Cursor cursor = context.getContentResolver().query(uri, projection, where.toString(), null, CalendarContract.Instances.BEGIN + " ASC"); if (cursor != null) { diff --git a/src/com/cyanogenmod/lockclock/misc/Constants.java b/src/com/cyanogenmod/lockclock/misc/Constants.java index 3c91171..bb783c3 100755 --- a/src/com/cyanogenmod/lockclock/misc/Constants.java +++ b/src/com/cyanogenmod/lockclock/misc/Constants.java @@ -31,6 +31,7 @@ public class Constants { public static final String CLOCK_SHOW_ALARM = "clock_show_alarm"; public static final String CLOCK_FONT_COLOR = "clock_font_color"; public static final String CLOCK_ALARM_FONT_COLOR = "clock_alarm_font_color"; + public static final String CLOCK_AM_PM_INDICATOR = "clock_am_pm_indicator"; public static final String SHOW_WEATHER = "show_weather"; public static final String WEATHER_USE_CUSTOM_LOCATION = "weather_use_custom_location"; diff --git a/src/com/cyanogenmod/lockclock/misc/Preferences.java b/src/com/cyanogenmod/lockclock/misc/Preferences.java index d3584a9..9979b50 100644 --- a/src/com/cyanogenmod/lockclock/misc/Preferences.java +++ b/src/com/cyanogenmod/lockclock/misc/Preferences.java @@ -57,6 +57,10 @@ public class Preferences { return getPrefs(context).getBoolean(Constants.CLOCK_FONT_DATE, true); } + public static boolean showAmPmIndicator(Context context) { + return getPrefs(context).getBoolean(Constants.CLOCK_AM_PM_INDICATOR, false); + } + public static int clockFontColor(Context context) { int color = Color.parseColor(getPrefs(context).getString(Constants.CLOCK_FONT_COLOR, Constants.DEFAULT_LIGHT_COLOR)); diff --git a/src/com/cyanogenmod/lockclock/misc/WidgetUtils.java b/src/com/cyanogenmod/lockclock/misc/WidgetUtils.java index dd9454f..242916e 100644 --- a/src/com/cyanogenmod/lockclock/misc/WidgetUtils.java +++ b/src/com/cyanogenmod/lockclock/misc/WidgetUtils.java @@ -30,6 +30,7 @@ import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Bitmap.Config; +import android.os.Build; import android.os.Bundle; import android.util.TypedValue; @@ -39,6 +40,7 @@ public class WidgetUtils { //=============================================================================================== // Widget display and resizing related functionality //=============================================================================================== + /** * Load a resource by Id and overlay with a specified color */ @@ -170,4 +172,11 @@ public class WidgetUtils { } return getDefaultClockIntent(context); } + + /** + * API level check to see if the new API 17 TextClock is available + */ + public static boolean isTextClockAvailable(){ + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; + } } diff --git a/src/com/cyanogenmod/lockclock/preference/ClockPreferences.java b/src/com/cyanogenmod/lockclock/preference/ClockPreferences.java index 6f71e7b..7a85a8c 100644 --- a/src/com/cyanogenmod/lockclock/preference/ClockPreferences.java +++ b/src/com/cyanogenmod/lockclock/preference/ClockPreferences.java @@ -21,9 +21,11 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.text.format.DateFormat; import com.cyanogenmod.lockclock.ClockWidgetProvider; import com.cyanogenmod.lockclock.R; @@ -35,6 +37,7 @@ public class ClockPreferences extends PreferenceFragment implements private Context mContext; private ListPreference mClockFontColor; private ListPreference mAlarmFontColor; + private CheckBoxPreference mAmPmToggle; @Override public void onCreate(Bundle savedInstanceState) { @@ -45,7 +48,10 @@ public class ClockPreferences extends PreferenceFragment implements mContext = getActivity(); mClockFontColor = (ListPreference) findPreference(Constants.CLOCK_FONT_COLOR); mAlarmFontColor = (ListPreference) findPreference(Constants.CLOCK_ALARM_FONT_COLOR); + mAmPmToggle = (CheckBoxPreference) findPreference(Constants.CLOCK_AM_PM_INDICATOR); + updateFontColorsSummary(); + updateAmPmToggle(); } @Override @@ -79,4 +85,12 @@ public class ClockPreferences extends PreferenceFragment implements mAlarmFontColor.setSummary(mAlarmFontColor.getEntry()); } } + + private void updateAmPmToggle() { + if (DateFormat.is24HourFormat(mContext)) { + mAmPmToggle.setEnabled(false); + } else { + mAmPmToggle.setEnabled(true); + } + } } |