Utils.java revision 3ea333d41c04fd5f3a5d45f540c17894874429e8
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; 27f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tangimport android.content.SharedPreferences.Editor; 28ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.database.Cursor; 29a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErikimport android.database.MatrixCursor; 30ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.Drawable; 31ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport android.graphics.drawable.GradientDrawable; 321ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.net.Uri; 33f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tangimport android.os.AsyncTask; 34d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chanimport android.os.Bundle; 35eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erikimport android.text.TextUtils; 36146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time; 371ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport android.util.Log; 38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 3956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashiimport java.util.Calendar; 401ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erikimport java.util.List; 41ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chanimport java.util.Map; 423ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tangimport java.util.TimeZone; 4356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 44146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class Utils { 45bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // Set to 0 until we have UI to perform undo 46bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public static final long UNDO_DELAY = 0; 47bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 4879f228124de7d98146ca526d743436f6419e2365Erik // For recurring events which instances of the series are being modified 4979f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_UNINITIALIZED = 0; 5079f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_SELECTED = 1; 5179f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_ALL_FOLLOWING = 2; 5279f228124de7d98146ca526d743436f6419e2365Erik public static final int MODIFY_ALL = 3; 5379f228124de7d98146ca526d743436f6419e2365Erik 5479f228124de7d98146ca526d743436f6419e2365Erik // When the edit event view finishes it passes back the appropriate exit code. 5579f228124de7d98146ca526d743436f6419e2365Erik public static final int DONE_REVERT = 0; 5679f228124de7d98146ca526d743436f6419e2365Erik public static final int DONE_SAVE = 1; 5779f228124de7d98146ca526d743436f6419e2365Erik public static final int DONE_DELETE = 2; 5879f228124de7d98146ca526d743436f6419e2365Erik 59ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF; 60ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int HIGH_ALPHA = 255 << 24; 61ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int MED_ALPHA = 180 << 24; 62ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan private static final int LOW_ALPHA = 150 << 24; 63ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 64ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String OPEN_EMAIL_MARKER = " <"; 65ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan protected static final String CLOSE_EMAIL_MARKER = ">"; 66ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 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"; 73d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 74d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan public static int getViewTypeFromIntentAndSharedPref(Activity activity) { 75d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan Bundle extras = activity.getIntent().getExtras(); 76d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(activity); 77d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 78d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan if (extras != null) { 79d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan if (extras.getBoolean(INTENT_KEY_DETAIL_VIEW, false)) { 80d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan // This is the "detail" view which is either agenda or day view 81d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return prefs.getInt(CalendarPreferenceActivity.KEY_DETAILED_VIEW, 82d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW); 83d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } else if (INTENT_VALUE_VIEW_TYPE_DAY.equals(extras.getString(INTENT_KEY_VIEW_TYPE))) { 84d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan // Not sure who uses this. This logic came from LaunchActivity 85d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return ViewType.DAY; 86d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 87d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 88d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 89d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan // Default to the last view 90d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return prefs.getInt(CalendarPreferenceActivity.KEY_START_VIEW, 91d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan CalendarPreferenceActivity.DEFAULT_START_VIEW); 92d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 93ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 94fbce65e53c7a111955f638db5bf8bee35381e5b7Erik public static String getSharedPreference(Context context, String key, String defaultValue) { 95a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 9645efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan return prefs.getString(key, defaultValue); 9745efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 9845efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 99d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan public static int getSharedPreference(Context context, String key, int defaultValue) { 100d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 101d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan return prefs.getInt(key, defaultValue); 102d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan } 103d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan 104f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang 105f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang private static class PreferenceCommitTask extends 106f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang AsyncTask<SharedPreferences.Editor, Integer, Boolean> { 107f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang @Override 108f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang protected Boolean doInBackground(Editor... params) { 109f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang Editor editor = params[0]; 110f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang return editor.commit(); 111f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang } 112f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang } 113f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang 114f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang /** 115f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * Commits the given shared preferences editor asynchronously in the 116f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * background. 117f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * 118f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * @param editor the editor to commit 119f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang */ 120f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang public static void commitSharedPreferencesEditor(Editor editor) { 121f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang (new PreferenceCommitTask()).execute(editor); 122f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang } 123f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang 124f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang /** 125f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * Asynchronously sets the preference with the given key to the given value 126f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * 127f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * @param context the context to use to get preferences from 128f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * @param key the key of the preference to set 129f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang * @param value the value to set 130f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang */ 131fbce65e53c7a111955f638db5bf8bee35381e5b7Erik public static void setSharedPreference(Context context, String key, String value) { 132a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 133f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang Editor editor = prefs.edit().putString(key, value); 134f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang commitSharedPreferencesEditor(editor); 13545efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan } 13645efa09d6e06f5569b2c0ae0dae0436dbfe6cb28Michael Chan 137d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan /** 138d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * Save default agenda/day/week/month view for next time 139d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * 140d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * @param context 141d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan * @param viewId {@link CalendarController.ViewType} 142d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan */ 143e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan static void setDefaultView(Context context, int viewId) { 144a17725e24d51b7a6f002dd5afd3270c8eeea0dbeJeff Hamilton SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 145e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan SharedPreferences.Editor editor = prefs.edit(); 146f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang 147d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan if (viewId == CalendarController.ViewType.AGENDA 148d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan || viewId == CalendarController.ViewType.DAY) { 149e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) detail start view only for Agenda and Day 150d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan editor.putInt(CalendarPreferenceActivity.KEY_DETAILED_VIEW, viewId); 151e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 152e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 153e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan // Record the (new) start view 154d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan editor.putInt(CalendarPreferenceActivity.KEY_START_VIEW, viewId); 155f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang 156f4ad4757de32ace6971cf4c3db7c395aa249001aMason Tang commitSharedPreferencesEditor(editor); 157e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan } 158e8aa59d4575d712601a133a9263acc23adbc8c17Michael Chan 159a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static MatrixCursor matrixCursorFromCursor(Cursor cursor) { 160a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik MatrixCursor newCursor = new MatrixCursor(cursor.getColumnNames()); 161a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = cursor.getColumnCount(); 162a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik String data[] = new String[numColumns]; 163a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik cursor.moveToPosition(-1); 164a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while (cursor.moveToNext()) { 165a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for (int i = 0; i < numColumns; i++) { 166a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik data[i] = cursor.getString(i); 167a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 168a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik newCursor.addRow(data); 169a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 170a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return newCursor; 171a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 172a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 173a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik /** 174a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * Compares two cursors to see if they contain the same data. 175a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * 176a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * @return Returns true of the cursors contain the same data and are not null, false 177a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik * otherwise 178a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik */ 179a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik public static boolean compareCursors(Cursor c1, Cursor c2) { 180a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if(c1 == null || c2 == null) { 181a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 182a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 183a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 184a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik int numColumns = c1.getColumnCount(); 185a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (numColumns != c2.getColumnCount()) { 186a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 187a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 188a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 189a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik if (c1.getCount() != c2.getCount()) { 190a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 191a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 192a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 193a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c1.moveToPosition(-1); 194a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik c2.moveToPosition(-1); 195a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik while(c1.moveToNext() && c2.moveToNext()) { 196a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik for(int i = 0; i < numColumns; i++) { 197eb10fa8bee049e0052b5cb53dcfbdaccef9f2740Erik if(!TextUtils.equals(c1.getString(i), c2.getString(i))) { 198a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return false; 199a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 200a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 201a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 202a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 203a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik return true; 204a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik } 205a144f86b41170e8ee7fe8d966cc51c5fc90cd44aErik 206146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 207146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * If the given intent specifies a time (in milliseconds since the epoch), 208146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * then that time is returned. Otherwise, the current time is returned. 209146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 210146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final long timeFromIntentInMillis(Intent intent) { 211146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the time was specified, then use that. Otherwise, use the current time. 2121ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Uri data = intent.getData(); 213146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1); 2141ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik if (millis == -1 && data != null && data.isHierarchical()) { 2151ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik List<String> path = data.getPathSegments(); 216eca5d33e4230cf6ac3acfe3fabf853f9275f98caErik if(path.size() == 2 && path.get(0).equals("time")) { 2171ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik try { 2181ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik millis = Long.valueOf(data.getLastPathSegment()); 2191ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } catch (NumberFormatException e) { 2201ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik Log.i("Calendar", "timeFromIntentInMillis: Data existed but no valid time " + 2211ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik "found. Using current time."); 2221ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2231ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 2241ef7f3ae2831dce8fa5e350f78ac4258c1a0a605Erik } 22576727b7a9cf780f200414548b9d454bf9a701e3eErik if (millis <= 0) { 226146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project millis = System.currentTimeMillis(); 227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return millis; 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 /** 2644c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * Returns a list joined together by the provided delimiter, for example, 2654c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * ["a", "b", "c"] could be joined into "a,b,c" 2664c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * 2674c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * @param things the things to join together 2684c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * @param delim the delimiter to use 2694c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang * @return a string contained the things joined together 2704c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang */ 2714c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang public static String join(List<?> things, String delim) { 2724c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang StringBuilder builder = new StringBuilder(); 2734c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang boolean first = true; 2744c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang for (Object thing : things) { 2754c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang if (first) { 2764c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang first = false; 2774c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } else { 2784c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang builder.append(delim); 2794c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } 2804c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang builder.append(thing.toString()); 2814c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } 2824c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang return builder.toString(); 2834c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang } 2844c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang 2854c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang /** 28656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Get first day of week as android.text.format.Time constant. 28756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return the first day of week in android.text.format.Time 28856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 2898e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang public static int getFirstDayOfWeek(Context context) { 2908e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 291d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan String pref = prefs.getString(CalendarPreferenceActivity.KEY_WEEK_START_DAY, 2928e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang CalendarPreferenceActivity.WEEK_START_DEFAULT); 2938e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang 2948e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang int startDay; 2958e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang if (CalendarPreferenceActivity.WEEK_START_DEFAULT.equals(pref)) { 2968e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang startDay = Calendar.getInstance().getFirstDayOfWeek(); 2978e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang } else { 2988e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang startDay = Integer.parseInt(pref); 2998e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang } 3008e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang 30156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi if (startDay == Calendar.SATURDAY) { 30256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SATURDAY; 30356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else if (startDay == Calendar.MONDAY) { 30456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.MONDAY; 30556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } else { 30656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return Time.SUNDAY; 30756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 30856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 30956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 31056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 31156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Saturday or not. 31256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param column the column position 31356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @param firstDayOfWeek the first day of week in android.text.format.Time 31456adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * @return true if the column is Saturday position 31556adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 31656adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSaturday(int column, int firstDayOfWeek) { 31756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 6) 31856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 5) 31956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 0); 32056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 32156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi 32256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi /** 32356adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi * Determine whether the column position is Sunday 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 Sunday position 32756adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi */ 32856adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi public static boolean isSunday(int column, int firstDayOfWeek) { 32956adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi return (firstDayOfWeek == Time.SUNDAY && column == 0) 33056adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.MONDAY && column == 6) 33156adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi || (firstDayOfWeek == Time.SATURDAY && column == 1); 33256adc7b3f9e62ada7f3708c5c7228e8ac5af1755Takaoka G. Tadashi } 333ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan 334ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan /** 3353ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * Convert given UTC time into current local time. 3363ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * 3373ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * @param recycle Time object to recycle, otherwise null. 3383ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang * @param utcTime Time to convert, in UTC. 3393ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang */ 3403ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang public static long convertUtcToLocal(Time recycle, long utcTime) { 3413ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang if (recycle == null) { 3423ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle = new Time(); 3433ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang } 3443ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle.timezone = Time.TIMEZONE_UTC; 3453ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle.set(utcTime); 3463ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang recycle.timezone = TimeZone.getDefault().getID(); 3473ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang return recycle.normalize(true); 3483ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang } 3493ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang 3503ea333d41c04fd5f3a5d45f540c17894874429e8Mason Tang /** 351ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * Scan through a cursor of calendars and check if names are duplicated. 352ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * 353ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * This travels a cursor containing calendar display names and fills in the provided map with 354ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * whether or not each name is repeated. 355ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param isDuplicateName The map to put the duplicate check results in. 356ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param cursor The query of calendars to check 357ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan * @param nameIndex The column of the query that contains the display name 358ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan */ 359ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan public static void checkForDuplicateNames(Map<String, Boolean> isDuplicateName, Cursor cursor, 360ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan int nameIndex) { 361ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.clear(); 362ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan cursor.moveToPosition(-1); 363ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan while (cursor.moveToNext()) { 364ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan String displayName = cursor.getString(nameIndex); 365ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan // Set it to true if we've seen this name before, false otherwise 366ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan if (displayName != null) { 367ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan isDuplicateName.put(displayName, isDuplicateName.containsKey(displayName)); 368ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 369ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 370ff6be831fc682374be6b78c13ecf5daca81f86d9Michael Chan } 3719138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 3729138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 3739138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * Null-safe object comparison 3749138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * @param s1 3759138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * @param s2 3769138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * @return 3779138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang */ 3789138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang public static boolean equals(Object o1, Object o2) { 3799138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang return o1 == null ? o2 == null : o1.equals(o2); 3809138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang } 381146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 382