Utils.java revision 275232dae58bb24e3360a779ada9d24601a99bcf
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 21d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chanimport com.android.calendar.CalendarController.ViewType; 22d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 23d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chanimport android.app.Activity; 24146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context; 25146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Intent; 26e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chanimport android.content.SharedPreferences; 27ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.database.Cursor; 28a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErikimport android.database.MatrixCursor; 29ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.Drawable; 30ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.GradientDrawable; 311ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.net.Uri; 32d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chanimport android.os.Bundle; 33eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erikimport android.text.TextUtils; 34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time; 351ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.util.Log; 36146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 3756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashiimport java.util.Calendar; 38235d59cf61769ec8ab777d81cd1ceb2e7530f439Erikimport java.util.HashSet; 391ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport java.util.List; 40ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport java.util.Map; 413ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tangimport java.util.TimeZone; 4256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 43146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class Utils { 443dc5e908a825b879978ba523d9099dc2255da9a5Erik private static final boolean DEBUG = true; 453dc5e908a825b879978ba523d9099dc2255da9a5Erik private static final String TAG = "CalUtils"; 46bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // Set to 0 until we have UI to perform undo 47bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public static final long UNDO_DELAY = 0; 48bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 4979f228124de7d98146ca526d743436f6419e2365Erik // For recurring events which instances of the series are being modified 5079f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_UNINITIALIZED = 0; 5179f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_SELECTED = 1; 5279f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_ALL_FOLLOWING = 2; 5379f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_ALL = 3; 5479f228124de7d98146ca526d743436f6419e2365Erik 5579f228124de7d98146ca526d743436f6419e2365Erik // When the edit event view finishes it passes back the appropriate exit code. 5679f228124de7d98146ca526d743436f6419e2365Erik public static final int DONE_REVERT = 0; 5779f228124de7d98146ca526d743436f6419e2365Erik public static final int DONE_SAVE = 1; 5879f228124de7d98146ca526d743436f6419e2365Erik public static final int DONE_DELETE = 2; 5979f228124de7d98146ca526d743436f6419e2365Erik 60ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF; 61ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int HIGH_ALPHA = 255 << 24; 62ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int MED_ALPHA = 180 << 24; 63ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int LOW_ALPHA = 150 << 24; 64ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 65ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String OPEN_EMAIL_MARKER = " <"; 66ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String CLOSE_EMAIL_MARKER = ">"; 67ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /* The corner should be rounded on the top right and bottom right */ 68ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final float[] CORNERS = new float[] {0, 0, 5, 5, 5, 5, 0, 0}; 69ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 70d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan public static final String INTENT_KEY_DETAIL_VIEW = "DETAIL_VIEW"; 71d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan public static final String INTENT_KEY_VIEW_TYPE = "VIEW"; 72d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan public static final String INTENT_VALUE_VIEW_TYPE_DAY = "DAY"; 73275232dae58bb24e3360a779ada9d24601a99bcfErik 74235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mFirstTZRequest = true; 75235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mTZQueryInProgress = false; 76235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 77235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static boolean mUseHomeTZ = false; 78235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private volatile static String mHomeTZ = Time.getCurrentTimezone(); 79235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 80235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik private static HashSet<Runnable> mTZCallbacks = new HashSet<Runnable>(); 81d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 82d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan public static int getViewTypeFromIntentAndSharedPref(Activity activity) { 83dd95df57c8c5a58a85c4c0effad5652dec14f621Erik Intent intent = activity.getIntent(); 84dd95df57c8c5a58a85c4c0effad5652dec14f621Erik Bundle extras = intent.getExtras(); 85d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(activity); 86d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 87dd95df57c8c5a58a85c4c0effad5652dec14f621Erik if (TextUtils.equals(intent.getAction(),Intent.ACTION_EDIT)) { 88dd95df57c8c5a58a85c4c0effad5652dec14f621Erik return ViewType.EDIT; 89dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 90d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan if (extras != null) { 91d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan if (extras.getBoolean(INTENT_KEY_DETAIL_VIEW, false)) { 92d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan // This is the "detail" view which is either agenda or day view 93d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return prefs.getInt(CalendarPreferenceActivity.KEY_DETAILED_VIEW, 94d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW); 95d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } else if (INTENT_VALUE_VIEW_TYPE_DAY.equals(extras.getString(INTENT_KEY_VIEW_TYPE))) { 96d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan // Not sure who uses this. This logic came from LaunchActivity 97d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return ViewType.DAY; 98d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 99d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 100d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 101d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan // Default to the last view 102d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return prefs.getInt(CalendarPreferenceActivity.KEY_START_VIEW, 103d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan CalendarPreferenceActivity.DEFAULT_START_VIEW); 104d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 105ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 106235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik /** 1073dc5e908a825b879978ba523d9099dc2255da9a5Erik * Writes a new home time zone to the db. 1083dc5e908a825b879978ba523d9099dc2255da9a5Erik * 1093dc5e908a825b879978ba523d9099dc2255da9a5Erik * Updates the home time zone in the db asynchronously and updates 1103dc5e908a825b879978ba523d9099dc2255da9a5Erik * the local cache. Sending a time zone of **tbd** will cause it to 1113dc5e908a825b879978ba523d9099dc2255da9a5Erik * be set to the device's time zone. null or empty tz will be ignored. 1123dc5e908a825b879978ba523d9099dc2255da9a5Erik * 1133dc5e908a825b879978ba523d9099dc2255da9a5Erik * @param context The calling activity 1143dc5e908a825b879978ba523d9099dc2255da9a5Erik * @param timeZone The time zone to set Calendar to, or **tbd** 1153dc5e908a825b879978ba523d9099dc2255da9a5Erik */ 1163dc5e908a825b879978ba523d9099dc2255da9a5Erik public static void setTimeZone(Context context, String timeZone) { 1173dc5e908a825b879978ba523d9099dc2255da9a5Erik if (TextUtils.isEmpty(timeZone)) { 1183dc5e908a825b879978ba523d9099dc2255da9a5Erik if (DEBUG) { 1193dc5e908a825b879978ba523d9099dc2255da9a5Erik Log.d(TAG, "Empty time zone, nothing to be done."); 1203dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1213dc5e908a825b879978ba523d9099dc2255da9a5Erik return; 1223dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1233dc5e908a825b879978ba523d9099dc2255da9a5Erik synchronized (mTZCallbacks) { 1243dc5e908a825b879978ba523d9099dc2255da9a5Erik if (CalendarPreferenceActivity.LOCAL_TZ.equals(timeZone)) { 1253dc5e908a825b879978ba523d9099dc2255da9a5Erik if (!mUseHomeTZ) { 1263dc5e908a825b879978ba523d9099dc2255da9a5Erik return; 1273dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1283dc5e908a825b879978ba523d9099dc2255da9a5Erik mUseHomeTZ = false; 1293dc5e908a825b879978ba523d9099dc2255da9a5Erik } else { 1303dc5e908a825b879978ba523d9099dc2255da9a5Erik if (TextUtils.equals(mHomeTZ, timeZone)) { 1313dc5e908a825b879978ba523d9099dc2255da9a5Erik return; 1323dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1333dc5e908a825b879978ba523d9099dc2255da9a5Erik mUseHomeTZ = true; 1343dc5e908a825b879978ba523d9099dc2255da9a5Erik mHomeTZ = timeZone; 1353dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1363dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1373dc5e908a825b879978ba523d9099dc2255da9a5Erik setSharedPreference(context, CalendarPreferenceActivity.KEY_HOME_TZ_ENABLED, mUseHomeTZ); 1383dc5e908a825b879978ba523d9099dc2255da9a5Erik if (mUseHomeTZ) { 1393dc5e908a825b879978ba523d9099dc2255da9a5Erik setSharedPreference(context, CalendarPreferenceActivity.KEY_HOME_TZ, mHomeTZ); 1403dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1413dc5e908a825b879978ba523d9099dc2255da9a5Erik // TODO async update db 1423dc5e908a825b879978ba523d9099dc2255da9a5Erik } 1433dc5e908a825b879978ba523d9099dc2255da9a5Erik 1443dc5e908a825b879978ba523d9099dc2255da9a5Erik /** 145235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * Gets the time zone that Calendar should be displayed in 146235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * 147235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * This is a helper method to get the appropriate time zone for Calendar. If this 148235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * is the first time this method has been called it will initiate an asynchronous 149235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * query to verify that the data in preferences is correct. The callback supplied 150235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * will only be called if this query returns a value other than what is stored in 151235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * preferences and should cause the calling activity to refresh anything that 152235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * depends on calling this method. 153235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * 154235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @param context The calling activity 155235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @param callback The runnable that should execute if a query returns new values 156235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik * @return The string value representing the time zone Calendar should display 157235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik */ 158235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik public static String getTimeZone(Context context, Runnable callback) { 159235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik synchronized (mTZCallbacks){ 160235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik if (mFirstTZRequest) { 161235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZQueryInProgress = true; 162235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mFirstTZRequest = false; 163235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 164235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 165235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mUseHomeTZ = prefs.getBoolean( 166235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik CalendarPreferenceActivity.KEY_HOME_TZ_ENABLED, false); 167235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mHomeTZ = prefs.getString( 168235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik CalendarPreferenceActivity.KEY_HOME_TZ, Time.getCurrentTimezone()); 169235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // TODO kick off async query 170235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // When the async query returns it should synchronize on 171235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // mTZCallbacks, update mUseHomeTZ, mHomeTZ, and the 172235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // preferences, set mTZQueryInProgress to false, and call all 173235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // the runnables in mTZCallbacks. 174235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik // TODO remove this line when we have a query 175235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZQueryInProgress = false; 176235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 177235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik if (mTZQueryInProgress) { 178235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik mTZCallbacks.add(callback); 179235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 180235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 181235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik return mUseHomeTZ ? mHomeTZ : Time.getCurrentTimezone(); 182235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik } 183235d59cf61769ec8ab777d81cd1ceb2e7530f439Erik 184fbce65e53c7a111955f638db5bf8bee35381e5b7Erik public static String getSharedPreference(Context context, String key, String defaultValue) { 185a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 18645efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan return prefs.getString(key, defaultValue); 18745efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 18845efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 189d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan public static int getSharedPreference(Context context, String key, int defaultValue) { 190d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 191d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return prefs.getInt(key, defaultValue); 192d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 193d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 194f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang /** 195f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * Asynchronously sets the preference with the given key to the given value 196f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * 197f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * @param context the context to use to get preferences from 198f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * @param key the key of the preference to set 199f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * @param value the value to set 200f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang */ 201fbce65e53c7a111955f638db5bf8bee35381e5b7Erik public static void setSharedPreference(Context context, String key, String value) { 202a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 20324fac46d6b87ce21d5e6a4b1c0fdcaa83d408997Brad Fitzpatrick prefs.edit().putString(key, value).apply(); 20445efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 20545efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 2063dc5e908a825b879978ba523d9099dc2255da9a5Erik static void setSharedPreference(Context context, String key, boolean value) { 2073dc5e908a825b879978ba523d9099dc2255da9a5Erik SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 2083dc5e908a825b879978ba523d9099dc2255da9a5Erik SharedPreferences.Editor editor = prefs.edit(); 2093dc5e908a825b879978ba523d9099dc2255da9a5Erik editor.putBoolean(key, value); 210275232dae58bb24e3360a779ada9d24601a99bcfErik editor.apply(); 2113dc5e908a825b879978ba523d9099dc2255da9a5Erik } 2123dc5e908a825b879978ba523d9099dc2255da9a5Erik 213d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan /** 214d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * Save default agenda/day/week/month view for next time 215d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * 216d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * @param context 217d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * @param viewId {@link CalendarController.ViewType} 218d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan */ 219e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan static void setDefaultView(Context context, int viewId) { 220a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 221e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan SharedPreferences.Editor editor = prefs.edit(); 222f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang 223d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan if (viewId == CalendarController.ViewType.AGENDA 224d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan || viewId == CalendarController.ViewType.DAY) { 225e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) detail start view only for Agenda and Day 226d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan editor.putInt(CalendarPreferenceActivity.KEY_DETAILED_VIEW, viewId); 227e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 228e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 229e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) start view 230d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan editor.putInt(CalendarPreferenceActivity.KEY_START_VIEW, viewId); 23124fac46d6b87ce21d5e6a4b1c0fdcaa83d408997Brad Fitzpatrick editor.apply(); 232e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 233e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 234a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static MatrixCursor matrixCursorFromCursor(Cursor cursor) { 235a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik MatrixCursor newCursor = new MatrixCursor(cursor.getColumnNames()); 236a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = cursor.getColumnCount(); 237a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik String data[] = new String[numColumns]; 238a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik cursor.moveToPosition(-1); 239a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while (cursor.moveToNext()) { 240a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for (int i = 0; i < numColumns; i++) { 241a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik data[i] = cursor.getString(i); 242a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 243a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik newCursor.addRow(data); 244a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 245a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return newCursor; 246a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 247a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 248a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik /** 249a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * Compares two cursors to see if they contain the same data. 250a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * 251a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * @return Returns true of the cursors contain the same data and are not null, false 252a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * otherwise 253a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik */ 254a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static boolean compareCursors(Cursor c1, Cursor c2) { 255a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if(c1 == null || c2 == null) { 256a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 257a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 258a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 259a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = c1.getColumnCount(); 260a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (numColumns != c2.getColumnCount()) { 261a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 262a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 263a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 264a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (c1.getCount() != c2.getCount()) { 265a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 266a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 267a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 268a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c1.moveToPosition(-1); 269a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c2.moveToPosition(-1); 270a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while(c1.moveToNext() && c2.moveToNext()) { 271a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for(int i = 0; i < numColumns; i++) { 272eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erik if(!TextUtils.equals(c1.getString(i), c2.getString(i))) { 273a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 274a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 275a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 276a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 277a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 278a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return true; 279a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 280a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 281146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 282146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * If the given intent specifies a time (in milliseconds since the epoch), 283146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * then that time is returned. Otherwise, the current time is returned. 284146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 285146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final long timeFromIntentInMillis(Intent intent) { 286146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the time was specified, then use that. Otherwise, use the current time. 2871ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Uri data = intent.getData(); 288146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1); 2891ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik if (millis == -1 && data != null && data.isHierarchical()) { 2901ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik List<String> path = data.getPathSegments(); 291eca5d33e4230cf6ac3acfe3fabf853f9275f98caErik if(path.size() == 2 && path.get(0).equals("time")) { 2921ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik try { 2931ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik millis = Long.valueOf(data.getLastPathSegment()); 2941ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } catch (NumberFormatException e) { 2951ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Log.i("Calendar", "timeFromIntentInMillis: Data existed but no valid time " + 2961ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik "found. Using current time."); 2971ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2981ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2991ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 30076727b7a9cf780f200414548b9d454bf9a701e3eErik if (millis <= 0) { 301146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project millis = System.currentTimeMillis(); 302146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 303146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return millis; 304146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 305146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 306ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan public static Drawable getColorChip(int color) { 307ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /* 308ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * We want the color chip to have a nice gradient using 309ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * the color of the calendar. To do this we use a GradientDrawable. 310ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * The color supplied has an alpha of FF so we first do: 311ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * color & 0x00FFFFFF 312ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * to clear the alpha. Then we add our alpha to it. 313ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * We use 3 colors to get a step effect where it starts off very 314ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * light and quickly becomes dark and then a slow transition to 315ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * be even darker. 316ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan */ 317ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan color &= CLEAR_ALPHA_MASK; 318ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int startColor = color | HIGH_ALPHA; 319ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int middleColor = color | MED_ALPHA; 320ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int endColor = color | LOW_ALPHA; 321ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int[] colors = new int[] {startColor, middleColor, endColor}; 322ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors); 323ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan d.setCornerRadii(CORNERS); 324ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan return d; 325ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 326ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 327146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 328146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Formats the given Time object so that it gives the month and year 329146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * (for example, "September 2007"). 330146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 331146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param time the time to format 332146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the string containing the weekday and the date 333146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 334ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan public static String formatMonthYear(Context context, Time time) { 335ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan return time.format(context.getResources().getString(R.string.month_year)); 336146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 337146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 338146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 3394c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * Returns a list joined together by the provided delimiter, for example, 3404c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * ["a", "b", "c"] could be joined into "a,b,c" 3414c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * 3424c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * @param things the things to join together 3434c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * @param delim the delimiter to use 3444c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * @return a string contained the things joined together 3454c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang */ 3464c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang public static String join(List<?> things, String delim) { 3474c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang StringBuilder builder = new StringBuilder(); 3484c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang boolean first = true; 3494c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang for (Object thing : things) { 3504c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang if (first) { 3514c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang first = false; 3524c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } else { 3534c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang builder.append(delim); 3544c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } 3554c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang builder.append(thing.toString()); 3564c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } 3574c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang return builder.toString(); 3584c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } 3594c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang 3604c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang /** 36156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Get first day of week as android.text.format.Time constant. 36256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return the first day of week in android.text.format.Time 36356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 3648e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang public static int getFirstDayOfWeek(Context context) { 3658e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 366d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan String pref = prefs.getString(CalendarPreferenceActivity.KEY_WEEK_START_DAY, 3678e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang CalendarPreferenceActivity.WEEK_START_DEFAULT); 3688e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang 3698e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang int startDay; 3708e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang if (CalendarPreferenceActivity.WEEK_START_DEFAULT.equals(pref)) { 3718e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang startDay = Calendar.getInstance().getFirstDayOfWeek(); 3728e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang } else { 3738e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang startDay = Integer.parseInt(pref); 3748e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang } 3758e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang 37656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi if (startDay == Calendar.SATURDAY) { 37756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SATURDAY; 37856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else if (startDay == Calendar.MONDAY) { 37956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.MONDAY; 38056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else { 38156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SUNDAY; 38256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 38356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 38456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 38556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 38656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Saturday or not. 38756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param column the column position 38856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param firstDayOfWeek the first day of week in android.text.format.Time 38956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return true if the column is Saturday position 39056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 39156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSaturday(int column, int firstDayOfWeek) { 39256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 6) 39356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 5) 39456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 0); 39556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 39656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 39756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 39856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Sunday or not. 39956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param column the column position 40056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param firstDayOfWeek the first day of week in android.text.format.Time 40156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return true if the column is Sunday position 40256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 40356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSunday(int column, int firstDayOfWeek) { 40456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 0) 40556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 6) 40656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 1); 40756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 408ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 409ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /** 4103ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * Convert given UTC time into current local time. 4113ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * 4123ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * @param recycle Time object to recycle, otherwise null. 4133ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * @param utcTime Time to convert, in UTC. 4143ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang */ 4153ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang public static long convertUtcToLocal(Time recycle, long utcTime) { 4163ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang if (recycle == null) { 4173ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle = new Time(); 4183ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang } 4193ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle.timezone = Time.TIMEZONE_UTC; 4203ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle.set(utcTime); 4213ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle.timezone = TimeZone.getDefault().getID(); 4223ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang return recycle.normalize(true); 4233ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang } 4243ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang 4253ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang /** 426ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * Scan through a cursor of calendars and check if names are duplicated. 427ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * 428ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * This travels a cursor containing calendar display names and fills in the provided map with 429ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * whether or not each name is repeated. 430ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param isDuplicateName The map to put the duplicate check results in. 431ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param cursor The query of calendars to check 432ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param nameIndex The column of the query that contains the display name 433ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan */ 434ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan public static void checkForDuplicateNames(Map<String, Boolean> isDuplicateName, Cursor cursor, 435ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int nameIndex) { 436ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.clear(); 437ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan cursor.moveToPosition(-1); 438ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan while (cursor.moveToNext()) { 439ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan String displayName = cursor.getString(nameIndex); 440ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan // Set it to true if we've seen this name before, false otherwise 441ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan if (displayName != null) { 442ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.put(displayName, isDuplicateName.containsKey(displayName)); 443ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 444ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 445ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 4469138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 4479138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 4489138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * Null-safe object comparison 4499138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * @param s1 4509138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * @param s2 4519138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * @return 4529138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang */ 4539138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang public static boolean equals(Object o1, Object o2) { 4549138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang return o1 == null ? o2 == null : o1.equals(o2); 4559138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang } 456146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 457