Utils.java revision 3dc5e908a825b879978ba523d9099dc2255da9a5
1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/* 2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 4146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * you may not use this file except in compliance with the License. 6146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * You may obtain a copy of the License at 7146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 8146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 10146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * See the License for the specific language governing permissions and 14146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * limitations under the License. 15146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 16146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 17146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpackage com.android.calendar; 18146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 19146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport static android.provider.Calendar.EVENT_BEGIN_TIME; 20e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 21146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context; 22146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Intent; 23e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chanimport android.content.SharedPreferences; 24ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.database.Cursor; 25a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErikimport android.database.MatrixCursor; 26ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.Drawable; 27ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.GradientDrawable; 281ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.net.Uri; 29eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erikimport android.text.TextUtils; 30146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time; 311ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.util.Log; 32146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.animation.AlphaAnimation; 33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.ViewFlipper; 34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 3556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashiimport java.util.Calendar; 36235d59cf61769ec8ab777d81cd1ceb2e7530f439Erikimport java.util.HashSet; 371ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport java.util.List; 38ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport java.util.Map; 3956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 40146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class Utils { 413dc5e908a825b879978ba523d9099dc2255da9a5Erik private static final boolean DEBUG = true; 423dc5e908a825b879978ba523d9099dc2255da9a5Erik private static final String TAG = "CalUtils"; 43ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF; 44ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int HIGH_ALPHA = 255 << 24; 45ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int MED_ALPHA = 180 << 24; 46ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int LOW_ALPHA = 150 << 24; 47ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 48ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String OPEN_EMAIL_MARKER = " <"; 49ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String CLOSE_EMAIL_MARKER = ">"; 50ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /* The corner should be rounded on the top right and bottom right */ 51ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final float[] CORNERS = new float[] {0, 0, 5, 5, 5, 5, 0, 0}; 52ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 53235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mFirstTZRequest = true; 54235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mTZQueryInProgress = false; 55235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 56235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mUseHomeTZ = false; 57235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static String mHomeTZ = Time.getCurrentTimezone(); 58235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 59235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private static HashSet<Runnable> mTZCallbacks = new HashSet<Runnable>(); 60ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 61146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static void startActivity(Context context, String className, long time) { 62146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW); 63146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 64146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project intent.setClassName(context, className); 65146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project intent.putExtra(EVENT_BEGIN_TIME, time); 6623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); 67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project context.startActivity(intent); 69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 70146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 7145efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan static String getSharedPreference(Context context, String key, String defaultValue) { 72a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 7345efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan return prefs.getString(key, defaultValue); 7445efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 7545efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 76235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik /** 773dc5e908a825b879978ba523d9099dc2255da9a5Erik * Writes a new home time zone to the db. 783dc5e908a825b879978ba523d9099dc2255da9a5Erik * 793dc5e908a825b879978ba523d9099dc2255da9a5Erik * Updates the home time zone in the db asynchronously and updates 803dc5e908a825b879978ba523d9099dc2255da9a5Erik * the local cache. Sending a time zone of **tbd** will cause it to 813dc5e908a825b879978ba523d9099dc2255da9a5Erik * be set to the device's time zone. null or empty tz will be ignored. 823dc5e908a825b879978ba523d9099dc2255da9a5Erik * 833dc5e908a825b879978ba523d9099dc2255da9a5Erik * @param context The calling activity 843dc5e908a825b879978ba523d9099dc2255da9a5Erik * @param timeZone The time zone to set Calendar to, or **tbd** 853dc5e908a825b879978ba523d9099dc2255da9a5Erik */ 863dc5e908a825b879978ba523d9099dc2255da9a5Erik public static void setTimeZone(Context context, String timeZone) { 873dc5e908a825b879978ba523d9099dc2255da9a5Erik if (TextUtils.isEmpty(timeZone)) { 883dc5e908a825b879978ba523d9099dc2255da9a5Erik if (DEBUG) { 893dc5e908a825b879978ba523d9099dc2255da9a5Erik Log.d(TAG, "Empty time zone, nothing to be done."); 903dc5e908a825b879978ba523d9099dc2255da9a5Erik } 913dc5e908a825b879978ba523d9099dc2255da9a5Erik return; 923dc5e908a825b879978ba523d9099dc2255da9a5Erik } 933dc5e908a825b879978ba523d9099dc2255da9a5Erik synchronized (mTZCallbacks) { 943dc5e908a825b879978ba523d9099dc2255da9a5Erik if (CalendarPreferenceActivity.LOCAL_TZ.equals(timeZone)) { 953dc5e908a825b879978ba523d9099dc2255da9a5Erik if (!mUseHomeTZ) { 963dc5e908a825b879978ba523d9099dc2255da9a5Erik return; 973dc5e908a825b879978ba523d9099dc2255da9a5Erik } 983dc5e908a825b879978ba523d9099dc2255da9a5Erik mUseHomeTZ = false; 993dc5e908a825b879978ba523d9099dc2255da9a5Erik } else { 1003dc5e908a825b879978ba523d9099dc2255da9a5Erik if (TextUtils.equals(mHomeTZ, timeZone)) { 1013dc5e908a825b879978ba523d9099dc2255da9a5Erik return; 1023dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1033dc5e908a825b879978ba523d9099dc2255da9a5Erik mUseHomeTZ = true; 1043dc5e908a825b879978ba523d9099dc2255da9a5Erik mHomeTZ = timeZone; 1053dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1063dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1073dc5e908a825b879978ba523d9099dc2255da9a5Erik setSharedPreference(context, CalendarPreferenceActivity.KEY_HOME_TZ_ENABLED, mUseHomeTZ); 1083dc5e908a825b879978ba523d9099dc2255da9a5Erik if (mUseHomeTZ) { 1093dc5e908a825b879978ba523d9099dc2255da9a5Erik setSharedPreference(context, CalendarPreferenceActivity.KEY_HOME_TZ, mHomeTZ); 1103dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1113dc5e908a825b879978ba523d9099dc2255da9a5Erik // TODO async update db 1123dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1133dc5e908a825b879978ba523d9099dc2255da9a5Erik 1143dc5e908a825b879978ba523d9099dc2255da9a5Erik /** 115235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * Gets the time zone that Calendar should be displayed in 116235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * 117235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * This is a helper method to get the appropriate time zone for Calendar. If this 118235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * is the first time this method has been called it will initiate an asynchronous 119235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * query to verify that the data in preferences is correct. The callback supplied 120235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * will only be called if this query returns a value other than what is stored in 121235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * preferences and should cause the calling activity to refresh anything that 122235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * depends on calling this method. 123235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * 124235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @param context The calling activity 125235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @param callback The runnable that should execute if a query returns new values 126235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @return The string value representing the time zone Calendar should display 127235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik */ 128235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik public static String getTimeZone(Context context, Runnable callback) { 129235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik synchronized (mTZCallbacks){ 130235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik if (mFirstTZRequest) { 131235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZQueryInProgress = true; 132235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mFirstTZRequest = false; 133235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 134235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 135235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mUseHomeTZ = prefs.getBoolean( 136235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik CalendarPreferenceActivity.KEY_HOME_TZ_ENABLED, false); 137235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mHomeTZ = prefs.getString( 138235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik CalendarPreferenceActivity.KEY_HOME_TZ, Time.getCurrentTimezone()); 139235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // TODO kick off async query 140235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // When the async query returns it should synchronize on 141235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // mTZCallbacks, update mUseHomeTZ, mHomeTZ, and the 142235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // preferences, set mTZQueryInProgress to false, and call all 143235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // the runnables in mTZCallbacks. 144235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // TODO remove this line when we have a query 145235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZQueryInProgress = false; 146235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 147235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik if (mTZQueryInProgress) { 148235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZCallbacks.add(callback); 149235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 150235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 151235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik return mUseHomeTZ ? mHomeTZ : Time.getCurrentTimezone(); 152235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 153235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 15445efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan static void setSharedPreference(Context context, String key, String value) { 155a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 15645efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan SharedPreferences.Editor editor = prefs.edit(); 15745efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan editor.putString(key, value); 15845efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan editor.commit(); 15945efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 16045efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 1613dc5e908a825b879978ba523d9099dc2255da9a5Erik static void setSharedPreference(Context context, String key, boolean value) { 1623dc5e908a825b879978ba523d9099dc2255da9a5Erik SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 1633dc5e908a825b879978ba523d9099dc2255da9a5Erik SharedPreferences.Editor editor = prefs.edit(); 1643dc5e908a825b879978ba523d9099dc2255da9a5Erik editor.putBoolean(key, value); 1653dc5e908a825b879978ba523d9099dc2255da9a5Erik editor.commit(); 1663dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1673dc5e908a825b879978ba523d9099dc2255da9a5Erik 168e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan static void setDefaultView(Context context, int viewId) { 169e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan String activityString = CalendarApplication.ACTIVITY_NAMES[viewId]; 170e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 171a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 172e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan SharedPreferences.Editor editor = prefs.edit(); 173e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan if (viewId == CalendarApplication.AGENDA_VIEW_ID || 174e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan viewId == CalendarApplication.DAY_VIEW_ID) { 175e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) detail start view only for Agenda and Day 176e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan editor.putString(CalendarPreferenceActivity.KEY_DETAILED_VIEW, activityString); 177e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 178e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 179e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) start view 180e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString); 181e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan editor.commit(); 182e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 183e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final Time timeFromIntent(Intent intent) { 185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Time time = new Time(); 186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.set(timeFromIntentInMillis(intent)); 187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return time; 188146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 190a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static MatrixCursor matrixCursorFromCursor(Cursor cursor) { 191a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik MatrixCursor newCursor = new MatrixCursor(cursor.getColumnNames()); 192a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = cursor.getColumnCount(); 193a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik String data[] = new String[numColumns]; 194a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik cursor.moveToPosition(-1); 195a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while (cursor.moveToNext()) { 196a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for (int i = 0; i < numColumns; i++) { 197a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik data[i] = cursor.getString(i); 198a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 199a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik newCursor.addRow(data); 200a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 201a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return newCursor; 202a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 203a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 204a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik /** 205a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * Compares two cursors to see if they contain the same data. 206a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * 207a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * @return Returns true of the cursors contain the same data and are not null, false 208a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * otherwise 209a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik */ 210a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static boolean compareCursors(Cursor c1, Cursor c2) { 211a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if(c1 == null || c2 == null) { 212a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 213a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 214a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 215a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = c1.getColumnCount(); 216a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (numColumns != c2.getColumnCount()) { 217a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 218a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 219a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 220a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (c1.getCount() != c2.getCount()) { 221a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 222a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 223a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 224a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c1.moveToPosition(-1); 225a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c2.moveToPosition(-1); 226a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while(c1.moveToNext() && c2.moveToNext()) { 227a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for(int i = 0; i < numColumns; i++) { 228eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erik if(!TextUtils.equals(c1.getString(i), c2.getString(i))) { 229a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 230a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 231a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 232a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 233a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 234a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return true; 235a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 236a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 238146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * If the given intent specifies a time (in milliseconds since the epoch), 239146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * then that time is returned. Otherwise, the current time is returned. 240146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 241146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final long timeFromIntentInMillis(Intent intent) { 242146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the time was specified, then use that. Otherwise, use the current time. 2431ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Uri data = intent.getData(); 244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1); 2451ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik if (millis == -1 && data != null && data.isHierarchical()) { 2461ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik List<String> path = data.getPathSegments(); 247eca5d33e4230cf6ac3acfe3fabf853f9275f98caErik if(path.size() == 2 && path.get(0).equals("time")) { 2481ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik try { 2491ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik millis = Long.valueOf(data.getLastPathSegment()); 2501ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } catch (NumberFormatException e) { 2511ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Log.i("Calendar", "timeFromIntentInMillis: Data existed but no valid time " + 2521ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik "found. Using current time."); 2531ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2541ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2551ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 25676727b7a9cf780f200414548b9d454bf9a701e3eErik if (millis <= 0) { 257146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project millis = System.currentTimeMillis(); 258146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 259146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return millis; 260146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 261146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 262146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final void applyAlphaAnimation(ViewFlipper v) { 263146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project AlphaAnimation in = new AlphaAnimation(0.0f, 1.0f); 264146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 265146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project in.setStartOffset(0); 266146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project in.setDuration(500); 267146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 268146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project AlphaAnimation out = new AlphaAnimation(1.0f, 0.0f); 269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project out.setStartOffset(0); 271146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project out.setDuration(500); 272146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 273146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project v.setInAnimation(in); 274146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project v.setOutAnimation(out); 275146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 276146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 277ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan public static Drawable getColorChip(int color) { 278ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /* 279ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * We want the color chip to have a nice gradient using 280ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * the color of the calendar. To do this we use a GradientDrawable. 281ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * The color supplied has an alpha of FF so we first do: 282ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * color & 0x00FFFFFF 283ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * to clear the alpha. Then we add our alpha to it. 284ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * We use 3 colors to get a step effect where it starts off very 285ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * light and quickly becomes dark and then a slow transition to 286ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * be even darker. 287ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan */ 288ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan color &= CLEAR_ALPHA_MASK; 289ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int startColor = color | HIGH_ALPHA; 290ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int middleColor = color | MED_ALPHA; 291ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int endColor = color | LOW_ALPHA; 292ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int[] colors = new int[] {startColor, middleColor, endColor}; 293ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors); 294ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan d.setCornerRadii(CORNERS); 295ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan return d; 296ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 297ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 298146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 299146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Formats the given Time object so that it gives the month and year 300146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * (for example, "September 2007"). 301146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 302146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param time the time to format 303146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the string containing the weekday and the date 304146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 305ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan public static String formatMonthYear(Context context, Time time) { 306ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan return time.format(context.getResources().getString(R.string.month_year)); 307146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 308146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 309146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // TODO: replace this with the correct i18n way to do this 310146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final String englishNthDay[] = { 311146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", 312146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", 313146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "20th", "21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th", 314146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "30th", "31st" 315146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 316146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 317146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static String formatNth(int nth) { 318146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return "the " + englishNthDay[nth]; 319146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 320146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 321146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 322d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * Returns a list joined together by the provided delimiter, for example, 323d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * ["a", "b", "c"] could be joined into "a,b,c" 324d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * 325d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * @param things the things to join together 326d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * @param delim the delimiter to use 327d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * @return a string contained the things joined together 328d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang */ 329d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang public static String join(List<?> things, String delim) { 330d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang StringBuilder builder = new StringBuilder(); 331d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang boolean first = true; 332d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang for (Object thing : things) { 333d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang if (first) { 334d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang first = false; 335d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } else { 336d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang builder.append(delim); 337d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } 338d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang builder.append(thing.toString()); 339d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } 340d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang return builder.toString(); 341d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } 342d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang 343d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang /** 344146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Sets the time to the beginning of the day (midnight) by clearing the 345146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * hour, minute, and second fields. 346146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 347146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project static void setTimeToStartOfDay(Time time) { 348146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.second = 0; 349146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.minute = 0; 350146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.hour = 0; 351146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 35256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 35356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 35456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Get first day of week as android.text.format.Time constant. 35556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return the first day of week in android.text.format.Time 35656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 35756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static int getFirstDayOfWeek() { 35856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi int startDay = Calendar.getInstance().getFirstDayOfWeek(); 35956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi if (startDay == Calendar.SATURDAY) { 36056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SATURDAY; 36156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else if (startDay == Calendar.MONDAY) { 36256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.MONDAY; 36356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else { 36456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SUNDAY; 36556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 36656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 36756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 36856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 36956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Saturday or not. 37056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param column the column position 37156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param firstDayOfWeek the first day of week in android.text.format.Time 37256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return true if the column is Saturday position 37356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 37456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSaturday(int column, int firstDayOfWeek) { 37556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 6) 37656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 5) 37756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 0); 37856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 37956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 38056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 38156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Sunday or not. 38256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param column the column position 38356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param firstDayOfWeek the first day of week in android.text.format.Time 38456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return true if the column is Sunday position 38556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 38656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSunday(int column, int firstDayOfWeek) { 38756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 0) 38856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 6) 38956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 1); 39056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 391ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 392ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /** 393ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * Scan through a cursor of calendars and check if names are duplicated. 394ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * 395ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * This travels a cursor containing calendar display names and fills in the provided map with 396ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * whether or not each name is repeated. 397ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param isDuplicateName The map to put the duplicate check results in. 398ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param cursor The query of calendars to check 399ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param nameIndex The column of the query that contains the display name 400ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan */ 401ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan public static void checkForDuplicateNames(Map<String, Boolean> isDuplicateName, Cursor cursor, 402ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int nameIndex) { 403ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.clear(); 404ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan cursor.moveToPosition(-1); 405ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan while (cursor.moveToNext()) { 406ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan String displayName = cursor.getString(nameIndex); 407ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan // Set it to true if we've seen this name before, false otherwise 408ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan if (displayName != null) { 409ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.put(displayName, isDuplicateName.containsKey(displayName)); 410ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 411ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 412ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 413146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 414