Utils.java revision 0b7c93a6b691b25ccbcd8d683774d3d0d351a8e9
1d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson/* 2d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * Copyright (C) 2012 The Android Open Source Project 3d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * 4d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * Licensed under the Apache License, Version 2.0 (the "License"); 5d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * you may not use this file except in compliance with the License. 6d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * You may obtain a copy of the License at 7d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * 8d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * http://www.apache.org/licenses/LICENSE-2.0 9d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * 10d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * Unless required by applicable law or agreed to in writing, software 11d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * distributed under the License is distributed on an "AS IS" BASIS, 12d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * See the License for the specific language governing permissions and 14d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * limitations under the License. 15d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson */ 16d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 17d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonpackage com.android.deskclock; 18d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 1978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.animation.Animator; 2078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.animation.AnimatorSet; 2178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.animation.ObjectAnimator; 2278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.animation.TimeInterpolator; 230b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultasimport android.app.AlarmManager; 240b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultasimport android.app.PendingIntent; 25d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport android.content.Context; 26d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport android.content.Intent; 27de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelsonimport android.content.SharedPreferences; 28d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport android.content.pm.PackageInfo; 29d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport android.content.pm.PackageManager.NameNotFoundException; 30d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelsonimport android.content.res.Resources; 3178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.graphics.Color; 3278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.graphics.Paint; 3378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.graphics.PorterDuff; 3478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.graphics.PorterDuffColorFilter; 35d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport android.net.Uri; 3678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.os.Handler; 37287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.os.SystemClock; 3878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.preference.PreferenceManager; 3978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.provider.Settings; 40d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport android.text.TextUtils; 4178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.text.format.DateFormat; 42d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport android.view.MenuItem; 4378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.view.View; 4478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.view.animation.AccelerateInterpolator; 4578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.view.animation.DecelerateInterpolator; 4678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport android.widget.TextView; 47d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 48de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelsonimport com.android.deskclock.stopwatch.Stopwatches; 4998b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultasimport com.android.deskclock.timer.Timers; 50d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelsonimport com.android.deskclock.worldclock.CityObj; 51de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson 52d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelsonimport java.text.Collator; 53d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelsonimport java.util.Arrays; 5478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport java.util.Calendar; 55d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelsonimport java.util.Comparator; 56d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonimport java.util.Locale; 57d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 58d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 59d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelsonpublic class Utils { 60d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson private final static String TAG = Utils.class.getName(); 61d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 62d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson private final static String PARAM_LANGUAGE_CODE = "hl"; 63d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 64d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson /** 65d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * Help URL query parameter key for the app version. 66d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson */ 67d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson private final static String PARAM_VERSION = "version"; 68d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 69d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson /** 70d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * Cached version code to prevent repeated calls to the package manager. 71d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson */ 72d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson private static String sCachedVersionCode = null; 73d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 7478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** 7578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein * Intent to be used for checking if a clock's date has changed. Must be every fifteen 7678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein * minutes because not all time zones are hour-locked. 7778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein **/ 7878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public static final String ACTION_ON_QUARTER_HOUR = "com.android.deskclock.ON_QUARTER_HOUR"; 79d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 8078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** Types that may be used for clock displays. **/ 8178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public static final String CLOCK_TYPE_DIGITAL = "digital"; 8278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public static final String CLOCK_TYPE_ANALOG = "analog"; 83d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 847048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson /** 857048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson * time format constants 867048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson */ 877048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson public final static String HOURS_24 = "kk"; 887048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson public final static String HOURS = "h"; 897048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson public final static String MINUTES = ":mm"; 907048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson 917048625adb7c349deab4c00b2d85bcf65c164ae5Isaac Katzenelson 92d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson public static void prepareHelpMenuItem(Context context, MenuItem helpMenuItem) { 93d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson String helpUrlString = context.getResources().getString(R.string.desk_clock_help_url); 94d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson if (TextUtils.isEmpty(helpUrlString)) { 95d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // The help url string is empty or null, so set the help menu item to be invisible. 96d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson helpMenuItem.setVisible(false); 97d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson return; 98d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson } 99d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // The help url string exists, so first add in some extra query parameters. 87 100d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson final Uri fullUri = uriWithAddedParameters(context, Uri.parse(helpUrlString)); 101d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 102d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // Then, create an intent that will be fired when the user 103d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // selects this help menu item. 104d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson Intent intent = new Intent(Intent.ACTION_VIEW, fullUri); 105d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 106d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 107d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 108d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // Set the intent to the help menu item, show the help menu item in the overflow 109d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // menu, and make it visible. 110d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson helpMenuItem.setIntent(intent); 111d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson helpMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); 112d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson helpMenuItem.setVisible(true); 113d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson } 114d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 115d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson /** 116d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * Adds two query parameters into the Uri, namely the language code and the version code 117d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * of the app's package as gotten via the context. 118d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson * @return the uri with added query parameters 119d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson */ 120d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson private static Uri uriWithAddedParameters(Context context, Uri baseUri) { 121d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson Uri.Builder builder = baseUri.buildUpon(); 122d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 123d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // Add in the preferred language 124d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson builder.appendQueryParameter(PARAM_LANGUAGE_CODE, Locale.getDefault().toString()); 125d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 126d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // Add in the package version code 127d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson if (sCachedVersionCode == null) { 128d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // There is no cached version code, so try to get it from the package manager. 129d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson try { 130d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // cache the version code 131d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson PackageInfo info = context.getPackageManager().getPackageInfo( 132d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson context.getPackageName(), 0); 133d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson sCachedVersionCode = Integer.toString(info.versionCode); 134d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 135d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // append the version code to the uri 136d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson builder.appendQueryParameter(PARAM_VERSION, sCachedVersionCode); 137d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson } catch (NameNotFoundException e) { 138d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // Cannot find the package name, so don't add in the version parameter 139d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // This shouldn't happen. 140d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson Log.wtf("Invalid package name for context " + e); 141d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson } 142d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson } else { 143d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson builder.appendQueryParameter(PARAM_VERSION, sCachedVersionCode); 144d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson } 145d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 146d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson // Build the full uri and return it 147d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson return builder.build(); 148d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson } 149d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson 150287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein public static long getTimeNow() { 151287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein return SystemClock.elapsedRealtime(); 152287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 153287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 15400cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein /** 15500cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein * Calculate the amount by which the radius of a CircleTimerView should be offset by the any 15600cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein * of the extra painted objects. 15700cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein */ 15800cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein public static float calculateRadiusOffset( 15900cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein float strokeSize, float diamondStrokeSize, float markerStrokeSize) { 16000cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein return Math.max(strokeSize, Math.max(diamondStrokeSize, markerStrokeSize)); 16100cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein } 16200cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein 16372332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein /** The pressed color used throughout the app. If this method is changed, it will not have 16472332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein * any effect on the button press states, and those must be changed separately. 16572332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein **/ 16672332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein public static int getPressedColorId() { 16772332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein return R.color.clock_red; 16872332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein } 16972332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein 17072332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein /** The un-pressed color used throughout the app. If this method is changed, it will not have 17172332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein * any effect on the button press states, and those must be changed separately. 17272332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein **/ 17372332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein public static int getGrayColorId() { 17472332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein return R.color.clock_gray; 17572332c2290d17c344ece074726f72b35ea469f31Sam Blitzstein } 176de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson 177de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson /** 178de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson * Clears the persistent data of stopwatch (start time, state, laps, etc...). 179de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson */ 180de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson public static void clearSwSharedPref(SharedPreferences prefs) { 181de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson SharedPreferences.Editor editor = prefs.edit(); 182de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson editor.remove (Stopwatches.PREF_START_TIME); 183de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson editor.remove (Stopwatches.PREF_ACCUM_TIME); 184de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson editor.remove (Stopwatches.PREF_STATE); 185de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson int lapNum = prefs.getInt(Stopwatches.PREF_LAP_NUM, Stopwatches.STOPWATCH_RESET); 186de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson for (int i = 0; i < lapNum; i++) { 187de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson String key = Stopwatches.PREF_LAP_TIME + Integer.toString(i); 188de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson editor.remove(key); 189de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson } 190de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson editor.remove(Stopwatches.PREF_LAP_NUM); 191de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson editor.apply(); 192de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson } 19398b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas 19498b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas /** 19598b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas * Broadcast a message to show the in-use timers in the notifications 19698b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas */ 19798b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas public static void showInUseNotifications(Context context) { 19898b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas Intent timerIntent = new Intent(); 19998b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas timerIntent.setAction(Timers.NOTIF_IN_USE_SHOW); 20098b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas context.sendBroadcast(timerIntent); 20198b2b05e7a0cebcd6e065bdd0b25cb6eb86b497cRobyn Coultas } 20278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 20378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** Runnable for use with screensaver and dream, to move the clock every minute. 20478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein * registerViews() must be called prior to posting. 20578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein */ 20678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public static class ScreensaverMoveSaverRunnable implements Runnable { 20778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein static final long MOVE_DELAY = 60000; // DeskClock.SCREEN_SAVER_MOVE_DELAY; 20878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein static final long SLIDE_TIME = 10000; 20978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein static final long FADE_TIME = 3000; 21078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 21178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein static final boolean SLIDE = false; 21278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 21378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein private View mContentView, mSaverView; 21478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein private final Handler mHandler; 21578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 21678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein private static TimeInterpolator mSlowStartWithBrakes; 21778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 21878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 21978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public ScreensaverMoveSaverRunnable(Handler handler) { 22078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mHandler = handler; 22178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mSlowStartWithBrakes = new TimeInterpolator() { 22278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein @Override 22378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public float getInterpolation(float x) { 22478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein return (float)(Math.cos((Math.pow(x,3) + 1) * Math.PI) / 2.0f) + 0.5f; 22578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 22678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein }; 22778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 22878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 22978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public void registerViews(View contentView, View saverView) { 23078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mContentView = contentView; 23178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mSaverView = saverView; 23278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 23378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 23478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein @Override 23578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public void run() { 23678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein long delay = MOVE_DELAY; 23778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (mContentView == null || mSaverView == null) { 23878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mHandler.removeCallbacks(this); 23978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mHandler.postDelayed(this, delay); 24078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein return; 24178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 24278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 24378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein final float xrange = mContentView.getWidth() - mSaverView.getWidth(); 24478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein final float yrange = mContentView.getHeight() - mSaverView.getHeight(); 24578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Log.v("xrange: "+xrange+" yrange: "+yrange); 24678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 24778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (xrange == 0 && yrange == 0) { 24878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein delay = 500; // back in a split second 24978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } else { 25078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein final int nextx = (int) (Math.random() * xrange); 25178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein final int nexty = (int) (Math.random() * yrange); 25278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 25378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (mSaverView.getAlpha() == 0f) { 25478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein // jump right there 25578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mSaverView.setX(nextx); 25678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mSaverView.setY(nexty); 25778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f) 25878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein .setDuration(FADE_TIME) 25978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein .start(); 26078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } else { 26178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein AnimatorSet s = new AnimatorSet(); 26278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator xMove = ObjectAnimator.ofFloat(mSaverView, 26378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein "x", mSaverView.getX(), nextx); 26478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator yMove = ObjectAnimator.ofFloat(mSaverView, 26578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein "y", mSaverView.getY(), nexty); 26678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 26778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator xShrink = ObjectAnimator.ofFloat(mSaverView, "scaleX", 1f, 0.85f); 26878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator xGrow = ObjectAnimator.ofFloat(mSaverView, "scaleX", 0.85f, 1f); 26978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 27078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator yShrink = ObjectAnimator.ofFloat(mSaverView, "scaleY", 1f, 0.85f); 27178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator yGrow = ObjectAnimator.ofFloat(mSaverView, "scaleY", 0.85f, 1f); 27278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein AnimatorSet shrink = new AnimatorSet(); shrink.play(xShrink).with(yShrink); 27378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein AnimatorSet grow = new AnimatorSet(); grow.play(xGrow).with(yGrow); 27478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 27578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator fadeout = ObjectAnimator.ofFloat(mSaverView, "alpha", 1f, 0f); 27678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Animator fadein = ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f); 27778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 27878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 27978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (SLIDE) { 28078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(xMove).with(yMove); 28178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.setDuration(SLIDE_TIME); 28278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 28378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(shrink.setDuration(SLIDE_TIME/2)); 28478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(grow.setDuration(SLIDE_TIME/2)).after(shrink); 28578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.setInterpolator(mSlowStartWithBrakes); 28678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } else { 28778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein AccelerateInterpolator accel = new AccelerateInterpolator(); 28878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein DecelerateInterpolator decel = new DecelerateInterpolator(); 28978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 29078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein shrink.setDuration(FADE_TIME).setInterpolator(accel); 29178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein fadeout.setDuration(FADE_TIME).setInterpolator(accel); 29278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein grow.setDuration(FADE_TIME).setInterpolator(decel); 29378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein fadein.setDuration(FADE_TIME).setInterpolator(decel); 29478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(shrink); 29578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(fadeout); 29678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(xMove.setDuration(0)).after(FADE_TIME); 29778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(yMove.setDuration(0)).after(FADE_TIME); 29878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(fadein).after(FADE_TIME); 29978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.play(grow).after(FADE_TIME); 30078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 30178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein s.start(); 30278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 30378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 30478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein long now = System.currentTimeMillis(); 30578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein long adjust = (now % 60000); 30678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein delay = delay 30778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein + (MOVE_DELAY - adjust) // minute aligned 30878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein - (SLIDE ? 0 : FADE_TIME) // start moving before the fade 30978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein ; 31078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 31178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 31278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mHandler.removeCallbacks(this); 31378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein mHandler.postDelayed(this, delay); 31478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 31578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 31678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 31778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** Setup to find out when the quarter-hour changes (e.g. Kathmandu is GMT+5:45) **/ 3180b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas private static long getAlarmOnQuarterHour() { 31978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Calendar nextQuarter = Calendar.getInstance(); 32078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein // Set 1 second to ensure quarter-hour threshold passed. 32178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein nextQuarter.set(Calendar.SECOND, 1); 32278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein int minute = nextQuarter.get(Calendar.MINUTE); 32378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein nextQuarter.add(Calendar.MINUTE, 15 - (minute % 15)); 32478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein long alarmOnQuarterHour = nextQuarter.getTimeInMillis(); 32578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (0 >= (alarmOnQuarterHour - System.currentTimeMillis()) 32678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein || (alarmOnQuarterHour - System.currentTimeMillis()) > 901000) { 32778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Log.wtf("quarterly alarm calculation error"); 32878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 32978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein return alarmOnQuarterHour; 33078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 33178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 3320b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas /** Setup alarm refresh when the quarter-hour changes **/ 3330b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas public static PendingIntent startAlarmOnQuarterHour(Context context) { 3340b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas if (context != null) { 3350b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas PendingIntent quarterlyIntent = PendingIntent.getBroadcast( 3360b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas context, 0, new Intent(Utils.ACTION_ON_QUARTER_HOUR), 0); 3370b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setRepeating( 3380b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas AlarmManager.RTC, getAlarmOnQuarterHour(), 3390b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas AlarmManager.INTERVAL_FIFTEEN_MINUTES, quarterlyIntent); 3400b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas return quarterlyIntent; 3410b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas } else { 3420b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas return null; 3430b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas } 3440b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas } 3450b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas 3460b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas public static void cancelAlarmOnQuarterHour(Context context, PendingIntent quarterlyIntent) { 3470b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas if (quarterlyIntent != null && context != null) { 3480b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).cancel( 3490b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas quarterlyIntent); 3500b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas } 3510b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas } 3520b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas 3530b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas public static PendingIntent refreshAlarmOnQuarterHour( 3540b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas Context context, PendingIntent quarterlyIntent) { 3550b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas cancelAlarmOnQuarterHour(context, quarterlyIntent); 3560b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas return startAlarmOnQuarterHour(context); 3570b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas } 3580b7c93a6b691b25ccbcd8d683774d3d0d351a8e9Robyn Coultas 35978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** 36078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein * For screensavers to set whether the digital or analog clock should be displayed. 36178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein * Returns the view to be displayed. 36278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein */ 36378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public static View setClockStyle(Context context, View digitalClock, View analogClock, 36478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein String clockStyleKey) { 36578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); 36678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein String defaultClockStyle = context.getResources().getString(R.string.default_clock_style); 36778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein String style = sharedPref.getString(clockStyleKey, defaultClockStyle); 36878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein View returnView; 36978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (style.equals(CLOCK_TYPE_ANALOG)) { 37078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein digitalClock.setVisibility(View.GONE); 37178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein analogClock.setVisibility(View.VISIBLE); 37278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein returnView = analogClock; 37378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } else { 37478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein digitalClock.setVisibility(View.VISIBLE); 37578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein analogClock.setVisibility(View.GONE); 37678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein returnView = digitalClock; 37778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 37878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 37978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein return returnView; 38078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 38178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 38278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** 38378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein * For screensavers to dim the lights if necessary. 38478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein */ 38578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein public static void dimClockView(boolean dim, View clockView) { 38678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Paint paint = new Paint(); 38778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein paint.setColor(Color.WHITE); 38878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein paint.setColorFilter(new PorterDuffColorFilter( 38978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein (dim ? 0x60FFFFFF : 0xC0FFFFFF), 39078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein PorterDuff.Mode.MULTIPLY)); 39178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein clockView.setLayerType(View.LAYER_TYPE_HARDWARE, paint); 39278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 39378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 39478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** Clock views can call this to refresh their alarm to the next upcoming value. **/ 395b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson public static void refreshAlarm(Context context, View clock) { 39678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein String nextAlarm = Settings.System.getString(context.getContentResolver(), 39778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Settings.System.NEXT_ALARM_FORMATTED); 39878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein TextView nextAlarmView; 399b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson nextAlarmView = (TextView) clock.findViewById(R.id.nextAlarm); 40078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (!TextUtils.isEmpty(nextAlarm) && nextAlarmView != null) { 40178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein nextAlarmView.setText( 40278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein context.getString(R.string.control_set_alarm_with_existing, nextAlarm)); 40378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein nextAlarmView.setContentDescription(context.getResources().getString( 40478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein R.string.next_alarm_description, nextAlarm)); 40578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein nextAlarmView.setVisibility(View.VISIBLE); 40678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } else { 40778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein nextAlarmView.setVisibility(View.GONE); 40878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 40978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 41078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 41178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein /** Clock views can call this to refresh their date. **/ 412b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson public static void updateDate( 413b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson String dateFormat, String dateFormatForAccessibility, View clock) { 41478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein Calendar cal = Calendar.getInstance(); 41578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein cal.setTimeInMillis(System.currentTimeMillis()); 41678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 41778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein CharSequence newDate = DateFormat.format(dateFormat, cal); 41878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein TextView dateDisplay; 419b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson dateDisplay = (TextView) clock.findViewById(R.id.date); 42078b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein if (dateDisplay != null) { 42178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein dateDisplay.setVisibility(View.VISIBLE); 42278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein dateDisplay.setText(newDate); 42378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein dateDisplay.setContentDescription(DateFormat.format(dateFormatForAccessibility, cal)); 42478b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 42578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 42678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 427d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson public static CityObj[] loadCitiesDataBase(Context c) { 428d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson final Collator collator = Collator.getInstance(); 429d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson Resources r = c.getResources(); 430d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson // Read strings array of name,timezone, id 431d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson // make sure the list are the same length 432d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson String[] cities = r.getStringArray(R.array.cities_names); 433d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson String[] timezones = r.getStringArray(R.array.cities_tz); 434d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson String[] ids = r.getStringArray(R.array.cities_id); 435d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson if (cities.length != timezones.length || ids.length != cities.length) { 436d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson Log.wtf("City lists sizes are not the same, cannot use the data"); 437d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson return null; 438d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson } 439d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson CityObj[] tempList = new CityObj[cities.length]; 440d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson for (int i = 0; i < cities.length; i++) { 441d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson tempList[i] = new CityObj(cities[i], timezones[i], ids[i]); 442d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson } 443d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson // Sort alphabetically 444d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson Arrays.sort(tempList, new Comparator<CityObj> () { 445d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson @Override 446d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson public int compare(CityObj c1, CityObj c2) { 447d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson Comparator<CityObj> mCollator; 448d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson return collator.compare(c1.mCityName, c2.mCityName); 449d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson } 450d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson }); 451d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson return tempList; 452d4bbc122b90c63c5906ad32c4652b72c9409fd44Isaac Katzenelson } 453d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson 454d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson public static String getCityName(CityObj city, CityObj dbCity) { 455d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson return (city.mCityId == null || dbCity == null) ? city.mCityName : dbCity.mCityName; 456d851e8a4b134028bd12f509312d31664e4c826ddIsaac Katzenelson } 457d2f8c51aba02f5e8cbbf82234ff453f305fba759Isaac Katzenelson} 458