Utils.java revision 235d59cf61769ec8ab777d81cd1ceb2e7530f439
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 { 41ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF; 42ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int HIGH_ALPHA = 255 << 24; 43ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int MED_ALPHA = 180 << 24; 44ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int LOW_ALPHA = 150 << 24; 45ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 46ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String OPEN_EMAIL_MARKER = " <"; 47ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String CLOSE_EMAIL_MARKER = ">"; 48ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 49ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /* The corner should be rounded on the top right and bottom right */ 50ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final float[] CORNERS = new float[] {0, 0, 5, 5, 5, 5, 0, 0}; 51ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 52235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mFirstTZRequest = true; 53235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mTZQueryInProgress = false; 54235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 55235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mUseHomeTZ = false; 56235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static String mHomeTZ = Time.getCurrentTimezone(); 57235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 58235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private static HashSet<Runnable> mTZCallbacks = new HashSet<Runnable>(); 59ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 60146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static void startActivity(Context context, String className, long time) { 61146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW); 62146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 63146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project intent.setClassName(context, className); 64146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project intent.putExtra(EVENT_BEGIN_TIME, time); 6523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); 66146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project context.startActivity(intent); 68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 7045efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan static String getSharedPreference(Context context, String key, String defaultValue) { 71a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 7245efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan return prefs.getString(key, defaultValue); 7345efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 7445efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 75235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik /** 76235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * Gets the time zone that Calendar should be displayed in 77235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * 78235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * This is a helper method to get the appropriate time zone for Calendar. If this 79235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * is the first time this method has been called it will initiate an asynchronous 80235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * query to verify that the data in preferences is correct. The callback supplied 81235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * will only be called if this query returns a value other than what is stored in 82235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * preferences and should cause the calling activity to refresh anything that 83235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * depends on calling this method. 84235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * 85235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @param context The calling activity 86235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @param callback The runnable that should execute if a query returns new values 87235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @return The string value representing the time zone Calendar should display 88235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik */ 89235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik public static String getTimeZone(Context context, Runnable callback) { 90235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik synchronized (mTZCallbacks){ 91235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik if (mFirstTZRequest) { 92235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZQueryInProgress = true; 93235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mFirstTZRequest = false; 94235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 95235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 96235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mUseHomeTZ = prefs.getBoolean( 97235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik CalendarPreferenceActivity.KEY_HOME_TZ_ENABLED, false); 98235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mHomeTZ = prefs.getString( 99235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik CalendarPreferenceActivity.KEY_HOME_TZ, Time.getCurrentTimezone()); 100235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // TODO kick off async query 101235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // When the async query returns it should synchronize on 102235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // mTZCallbacks, update mUseHomeTZ, mHomeTZ, and the 103235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // preferences, set mTZQueryInProgress to false, and call all 104235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // the runnables in mTZCallbacks. 105235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // TODO remove this line when we have a query 106235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZQueryInProgress = false; 107235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 108235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik if (mTZQueryInProgress) { 109235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZCallbacks.add(callback); 110235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 111235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 112235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik return mUseHomeTZ ? mHomeTZ : Time.getCurrentTimezone(); 113235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 114235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 11545efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan static void setSharedPreference(Context context, String key, String value) { 116a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 11745efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan SharedPreferences.Editor editor = prefs.edit(); 11845efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan editor.putString(key, value); 11945efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan editor.commit(); 12045efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 12145efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 122e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan static void setDefaultView(Context context, int viewId) { 123e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan String activityString = CalendarApplication.ACTIVITY_NAMES[viewId]; 124e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 125a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 126e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan SharedPreferences.Editor editor = prefs.edit(); 127e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan if (viewId == CalendarApplication.AGENDA_VIEW_ID || 128e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan viewId == CalendarApplication.DAY_VIEW_ID) { 129e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) detail start view only for Agenda and Day 130e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan editor.putString(CalendarPreferenceActivity.KEY_DETAILED_VIEW, activityString); 131e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 132e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 133e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) start view 134e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString); 135e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan editor.commit(); 136e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 137e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 138146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final Time timeFromIntent(Intent intent) { 139146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Time time = new Time(); 140146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.set(timeFromIntentInMillis(intent)); 141146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return time; 142146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 143146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 144a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static MatrixCursor matrixCursorFromCursor(Cursor cursor) { 145a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik MatrixCursor newCursor = new MatrixCursor(cursor.getColumnNames()); 146a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = cursor.getColumnCount(); 147a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik String data[] = new String[numColumns]; 148a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik cursor.moveToPosition(-1); 149a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while (cursor.moveToNext()) { 150a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for (int i = 0; i < numColumns; i++) { 151a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik data[i] = cursor.getString(i); 152a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 153a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik newCursor.addRow(data); 154a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 155a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return newCursor; 156a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 157a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 158a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik /** 159a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * Compares two cursors to see if they contain the same data. 160a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * 161a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * @return Returns true of the cursors contain the same data and are not null, false 162a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * otherwise 163a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik */ 164a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static boolean compareCursors(Cursor c1, Cursor c2) { 165a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if(c1 == null || c2 == null) { 166a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 167a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 168a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 169a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = c1.getColumnCount(); 170a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (numColumns != c2.getColumnCount()) { 171a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 172a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 173a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 174a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (c1.getCount() != c2.getCount()) { 175a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 176a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 177a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 178a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c1.moveToPosition(-1); 179a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c2.moveToPosition(-1); 180a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while(c1.moveToNext() && c2.moveToNext()) { 181a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for(int i = 0; i < numColumns; i++) { 182eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erik if(!TextUtils.equals(c1.getString(i), c2.getString(i))) { 183a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 184a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 185a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 186a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 187a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 188a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return true; 189a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 190a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 192146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * If the given intent specifies a time (in milliseconds since the epoch), 193146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * then that time is returned. Otherwise, the current time is returned. 194146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 195146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final long timeFromIntentInMillis(Intent intent) { 196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the time was specified, then use that. Otherwise, use the current time. 1971ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Uri data = intent.getData(); 198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1); 1991ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik if (millis == -1 && data != null && data.isHierarchical()) { 2001ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik List<String> path = data.getPathSegments(); 201eca5d33e4230cf6ac3acfe3fabf853f9275f98caErik if(path.size() == 2 && path.get(0).equals("time")) { 2021ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik try { 2031ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik millis = Long.valueOf(data.getLastPathSegment()); 2041ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } catch (NumberFormatException e) { 2051ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Log.i("Calendar", "timeFromIntentInMillis: Data existed but no valid time " + 2061ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik "found. Using current time."); 2071ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2081ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2091ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 21076727b7a9cf780f200414548b9d454bf9a701e3eErik if (millis <= 0) { 211146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project millis = System.currentTimeMillis(); 212146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 213146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return millis; 214146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 215146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 216146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final void applyAlphaAnimation(ViewFlipper v) { 217146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project AlphaAnimation in = new AlphaAnimation(0.0f, 1.0f); 218146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 219146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project in.setStartOffset(0); 220146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project in.setDuration(500); 221146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 222146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project AlphaAnimation out = new AlphaAnimation(1.0f, 0.0f); 223146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 224146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project out.setStartOffset(0); 225146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project out.setDuration(500); 226146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project v.setInAnimation(in); 228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project v.setOutAnimation(out); 229146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 230146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 231ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan public static Drawable getColorChip(int color) { 232ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /* 233ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * We want the color chip to have a nice gradient using 234ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * the color of the calendar. To do this we use a GradientDrawable. 235ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * The color supplied has an alpha of FF so we first do: 236ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * color & 0x00FFFFFF 237ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * to clear the alpha. Then we add our alpha to it. 238ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * We use 3 colors to get a step effect where it starts off very 239ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * light and quickly becomes dark and then a slow transition to 240ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * be even darker. 241ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan */ 242ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan color &= CLEAR_ALPHA_MASK; 243ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int startColor = color | HIGH_ALPHA; 244ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int middleColor = color | MED_ALPHA; 245ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int endColor = color | LOW_ALPHA; 246ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int[] colors = new int[] {startColor, middleColor, endColor}; 247ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors); 248ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan d.setCornerRadii(CORNERS); 249ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan return d; 250ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 251ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 252146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 253146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Formats the given Time object so that it gives the month and year 254146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * (for example, "September 2007"). 255146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 256146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param time the time to format 257146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the string containing the weekday and the date 258146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 259ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan public static String formatMonthYear(Context context, Time time) { 260ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan return time.format(context.getResources().getString(R.string.month_year)); 261146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 262146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 263146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // TODO: replace this with the correct i18n way to do this 264146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final String englishNthDay[] = { 265146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", 266146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", 267146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "20th", "21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th", 268146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project "30th", "31st" 269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 271146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static String formatNth(int nth) { 272146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return "the " + englishNthDay[nth]; 273146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 274146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 275146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 276d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * Returns a list joined together by the provided delimiter, for example, 277d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * ["a", "b", "c"] could be joined into "a,b,c" 278d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * 279d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * @param things the things to join together 280d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * @param delim the delimiter to use 281d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang * @return a string contained the things joined together 282d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang */ 283d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang public static String join(List<?> things, String delim) { 284d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang StringBuilder builder = new StringBuilder(); 285d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang boolean first = true; 286d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang for (Object thing : things) { 287d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang if (first) { 288d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang first = false; 289d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } else { 290d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang builder.append(delim); 291d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } 292d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang builder.append(thing.toString()); 293d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } 294d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang return builder.toString(); 295d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang } 296d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang 297d7c7f2ab6fdb55451ead2d54819ba8f37af2d0a7Mason Tang /** 298146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Sets the time to the beginning of the day (midnight) by clearing the 299146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * hour, minute, and second fields. 300146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 301146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project static void setTimeToStartOfDay(Time time) { 302146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.second = 0; 303146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.minute = 0; 304146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.hour = 0; 305146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 30656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 30756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 30856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Get first day of week as android.text.format.Time constant. 30956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return the first day of week in android.text.format.Time 31056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 31156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static int getFirstDayOfWeek() { 31256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi int startDay = Calendar.getInstance().getFirstDayOfWeek(); 31356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi if (startDay == Calendar.SATURDAY) { 31456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SATURDAY; 31556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else if (startDay == Calendar.MONDAY) { 31656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.MONDAY; 31756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else { 31856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SUNDAY; 31956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 32056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 32156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 32256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 32356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Saturday or not. 32456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param column the column position 32556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param firstDayOfWeek the first day of week in android.text.format.Time 32656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return true if the column is Saturday position 32756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 32856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSaturday(int column, int firstDayOfWeek) { 32956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 6) 33056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 5) 33156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 0); 33256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 33356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 33456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 33556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Sunday or not. 33656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param column the column position 33756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param firstDayOfWeek the first day of week in android.text.format.Time 33856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return true if the column is Sunday position 33956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 34056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSunday(int column, int firstDayOfWeek) { 34156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 0) 34256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 6) 34356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 1); 34456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 345ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 346ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /** 347ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * Scan through a cursor of calendars and check if names are duplicated. 348ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * 349ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * This travels a cursor containing calendar display names and fills in the provided map with 350ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * whether or not each name is repeated. 351ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param isDuplicateName The map to put the duplicate check results in. 352ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param cursor The query of calendars to check 353ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param nameIndex The column of the query that contains the display name 354ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan */ 355ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan public static void checkForDuplicateNames(Map<String, Boolean> isDuplicateName, Cursor cursor, 356ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int nameIndex) { 357ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.clear(); 358ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan cursor.moveToPosition(-1); 359ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan while (cursor.moveToNext()) { 360ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan String displayName = cursor.getString(nameIndex); 361ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan // Set it to true if we've seen this name before, false otherwise 362ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan if (displayName != null) { 363ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.put(displayName, isDuplicateName.containsKey(displayName)); 364ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 365ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 366ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 367146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 368