Utils.java revision dc75d7711c7786e3a0c0752d6dca4dbc3e63895b
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.calendar; 18 19import static android.provider.Calendar.EVENT_BEGIN_TIME; 20 21import android.content.Context; 22import android.content.Intent; 23import android.content.SharedPreferences; 24import android.database.Cursor; 25import android.database.MatrixCursor; 26import android.graphics.drawable.Drawable; 27import android.graphics.drawable.GradientDrawable; 28import android.net.Uri; 29import android.text.TextUtils; 30import android.text.format.Time; 31import android.util.Log; 32import android.view.animation.AlphaAnimation; 33import android.widget.ViewFlipper; 34 35import java.util.Calendar; 36import java.util.List; 37import java.util.Map; 38 39public class Utils { 40 // Set to 0 until we have UI to perform undo 41 public static final long UNDO_DELAY = 0; 42 43 private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF; 44 private static final int HIGH_ALPHA = 255 << 24; 45 private static final int MED_ALPHA = 180 << 24; 46 private static final int LOW_ALPHA = 150 << 24; 47 48 protected static final String OPEN_EMAIL_MARKER = " <"; 49 protected static final String CLOSE_EMAIL_MARKER = ">"; 50 51 /* The corner should be rounded on the top right and bottom right */ 52 private static final float[] CORNERS = new float[] {0, 0, 5, 5, 5, 5, 0, 0}; 53 54 55 public static void startActivity(Context context, String className, long time) { 56 Intent intent = new Intent(Intent.ACTION_VIEW); 57 58 intent.setClassName(context, className); 59 intent.putExtra(EVENT_BEGIN_TIME, time); 60 intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); 61 62 context.startActivity(intent); 63 } 64 65 static String getSharedPreference(Context context, String key, String defaultValue) { 66 SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 67 return prefs.getString(key, defaultValue); 68 } 69 70 static void setSharedPreference(Context context, String key, String value) { 71 SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 72 SharedPreferences.Editor editor = prefs.edit(); 73 editor.putString(key, value); 74 editor.commit(); 75 } 76 77 static void setDefaultView(Context context, int viewId) { 78 String activityString = CalendarApplication.ACTIVITY_NAMES[viewId]; 79 80 SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(context); 81 SharedPreferences.Editor editor = prefs.edit(); 82 if (viewId == CalendarApplication.AGENDA_VIEW_ID || 83 viewId == CalendarApplication.DAY_VIEW_ID) { 84 // Record the (new) detail start view only for Agenda and Day 85 editor.putString(CalendarPreferenceActivity.KEY_DETAILED_VIEW, activityString); 86 } 87 88 // Record the (new) start view 89 editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString); 90 editor.commit(); 91 } 92 93 public static final Time timeFromIntent(Intent intent) { 94 Time time = new Time(); 95 time.set(timeFromIntentInMillis(intent)); 96 return time; 97 } 98 99 public static MatrixCursor matrixCursorFromCursor(Cursor cursor) { 100 MatrixCursor newCursor = new MatrixCursor(cursor.getColumnNames()); 101 int numColumns = cursor.getColumnCount(); 102 String data[] = new String[numColumns]; 103 cursor.moveToPosition(-1); 104 while (cursor.moveToNext()) { 105 for (int i = 0; i < numColumns; i++) { 106 data[i] = cursor.getString(i); 107 } 108 newCursor.addRow(data); 109 } 110 return newCursor; 111 } 112 113 /** 114 * Compares two cursors to see if they contain the same data. 115 * 116 * @return Returns true of the cursors contain the same data and are not null, false 117 * otherwise 118 */ 119 public static boolean compareCursors(Cursor c1, Cursor c2) { 120 if(c1 == null || c2 == null) { 121 return false; 122 } 123 124 int numColumns = c1.getColumnCount(); 125 if (numColumns != c2.getColumnCount()) { 126 return false; 127 } 128 129 if (c1.getCount() != c2.getCount()) { 130 return false; 131 } 132 133 c1.moveToPosition(-1); 134 c2.moveToPosition(-1); 135 while(c1.moveToNext() && c2.moveToNext()) { 136 for(int i = 0; i < numColumns; i++) { 137 if(!TextUtils.equals(c1.getString(i), c2.getString(i))) { 138 return false; 139 } 140 } 141 } 142 143 return true; 144 } 145 146 /** 147 * If the given intent specifies a time (in milliseconds since the epoch), 148 * then that time is returned. Otherwise, the current time is returned. 149 */ 150 public static final long timeFromIntentInMillis(Intent intent) { 151 // If the time was specified, then use that. Otherwise, use the current time. 152 Uri data = intent.getData(); 153 long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1); 154 if (millis == -1 && data != null && data.isHierarchical()) { 155 List<String> path = data.getPathSegments(); 156 if(path.size() == 2 && path.get(0).equals("time")) { 157 try { 158 millis = Long.valueOf(data.getLastPathSegment()); 159 } catch (NumberFormatException e) { 160 Log.i("Calendar", "timeFromIntentInMillis: Data existed but no valid time " + 161 "found. Using current time."); 162 } 163 } 164 } 165 if (millis <= 0) { 166 millis = System.currentTimeMillis(); 167 } 168 return millis; 169 } 170 171 public static final void applyAlphaAnimation(ViewFlipper v) { 172 AlphaAnimation in = new AlphaAnimation(0.0f, 1.0f); 173 174 in.setStartOffset(0); 175 in.setDuration(500); 176 177 AlphaAnimation out = new AlphaAnimation(1.0f, 0.0f); 178 179 out.setStartOffset(0); 180 out.setDuration(500); 181 182 v.setInAnimation(in); 183 v.setOutAnimation(out); 184 } 185 186 public static Drawable getColorChip(int color) { 187 /* 188 * We want the color chip to have a nice gradient using 189 * the color of the calendar. To do this we use a GradientDrawable. 190 * The color supplied has an alpha of FF so we first do: 191 * color & 0x00FFFFFF 192 * to clear the alpha. Then we add our alpha to it. 193 * We use 3 colors to get a step effect where it starts off very 194 * light and quickly becomes dark and then a slow transition to 195 * be even darker. 196 */ 197 color &= CLEAR_ALPHA_MASK; 198 int startColor = color | HIGH_ALPHA; 199 int middleColor = color | MED_ALPHA; 200 int endColor = color | LOW_ALPHA; 201 int[] colors = new int[] {startColor, middleColor, endColor}; 202 GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors); 203 d.setCornerRadii(CORNERS); 204 return d; 205 } 206 207 /** 208 * Formats the given Time object so that it gives the month and year 209 * (for example, "September 2007"). 210 * 211 * @param time the time to format 212 * @return the string containing the weekday and the date 213 */ 214 public static String formatMonthYear(Context context, Time time) { 215 return time.format(context.getResources().getString(R.string.month_year)); 216 } 217 218 /** 219 * Sets the time to the beginning of the day (midnight) by clearing the 220 * hour, minute, and second fields. 221 */ 222 static void setTimeToStartOfDay(Time time) { 223 time.second = 0; 224 time.minute = 0; 225 time.hour = 0; 226 } 227 228 /** 229 * Get first day of week as android.text.format.Time constant. 230 * @return the first day of week in android.text.format.Time 231 */ 232 public static int getFirstDayOfWeek() { 233 int startDay = Calendar.getInstance().getFirstDayOfWeek(); 234 if (startDay == Calendar.SATURDAY) { 235 return Time.SATURDAY; 236 } else if (startDay == Calendar.MONDAY) { 237 return Time.MONDAY; 238 } else { 239 return Time.SUNDAY; 240 } 241 } 242 243 /** 244 * Determine whether the column position is Saturday or not. 245 * @param column the column position 246 * @param firstDayOfWeek the first day of week in android.text.format.Time 247 * @return true if the column is Saturday position 248 */ 249 public static boolean isSaturday(int column, int firstDayOfWeek) { 250 return (firstDayOfWeek == Time.SUNDAY && column == 6) 251 || (firstDayOfWeek == Time.MONDAY && column == 5) 252 || (firstDayOfWeek == Time.SATURDAY && column == 0); 253 } 254 255 /** 256 * Determine whether the column position is Sunday or not. 257 * @param column the column position 258 * @param firstDayOfWeek the first day of week in android.text.format.Time 259 * @return true if the column is Sunday position 260 */ 261 public static boolean isSunday(int column, int firstDayOfWeek) { 262 return (firstDayOfWeek == Time.SUNDAY && column == 0) 263 || (firstDayOfWeek == Time.MONDAY && column == 6) 264 || (firstDayOfWeek == Time.SATURDAY && column == 1); 265 } 266 267 /** 268 * Scan through a cursor of calendars and check if names are duplicated. 269 * 270 * This travels a cursor containing calendar display names and fills in the provided map with 271 * whether or not each name is repeated. 272 * @param isDuplicateName The map to put the duplicate check results in. 273 * @param cursor The query of calendars to check 274 * @param nameIndex The column of the query that contains the display name 275 */ 276 public static void checkForDuplicateNames(Map<String, Boolean> isDuplicateName, Cursor cursor, 277 int nameIndex) { 278 isDuplicateName.clear(); 279 cursor.moveToPosition(-1); 280 while (cursor.moveToNext()) { 281 String displayName = cursor.getString(nameIndex); 282 // Set it to true if we've seen this name before, false otherwise 283 if (displayName != null) { 284 isDuplicateName.put(displayName, isDuplicateName.containsKey(displayName)); 285 } 286 } 287 } 288} 289