blob: 25af209581f6b34fd9af7927c1f1e4c6d7a18392 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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 android.provider;
18
RoboErikc2d53302011-06-03 09:37:58 -070019
RoboErik36726962011-06-14 14:01:15 -070020import android.annotation.SdkConstant;
21import android.annotation.SdkConstant.SdkConstantType;
Michael Chan37960c72012-04-19 00:18:13 -070022import android.app.Activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.app.AlarmManager;
24import android.app.PendingIntent;
Marc Blank64a556d2010-02-25 12:53:16 -080025import android.content.ContentProviderClient;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.content.ContentResolver;
27import android.content.ContentUris;
28import android.content.ContentValues;
29import android.content.Context;
Fred Quintana328c0e72009-12-07 14:52:28 -080030import android.content.CursorEntityIterator;
31import android.content.Entity;
Marc Blank64a556d2010-02-25 12:53:16 -080032import android.content.EntityIterator;
33import android.content.Intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.database.Cursor;
Fred Quintana328c0e72009-12-07 14:52:28 -080035import android.database.DatabaseUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.net.Uri;
Michael Chancdaeafd2009-10-29 00:11:58 -070037import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.text.format.DateUtils;
39import android.text.format.Time;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
42/**
RoboErik260598d2011-06-13 17:12:12 -070043 * <p>
44 * The contract between the calendar provider and applications. Contains
45 * definitions for the supported URIs and data columns.
46 * </p>
47 * <h3>Overview</h3>
48 * <p>
49 * CalendarContract defines the data model of calendar and event related
50 * information. This data is stored in a number of tables:
51 * </p>
52 * <ul>
53 * <li>The {@link Calendars} table holds the calendar specific information. Each
54 * row in this table contains the details for a single calendar, such as the
55 * name, color, sync info, etc.</li>
56 * <li>The {@link Events} table holds the event specific information. Each row
57 * in this table has the info for a single event. It contains information such
58 * as event title, location, start time, end time, etc. The event can occur
59 * one-time or can recur multiple times. Attendees, reminders, and extended
60 * properties are stored on separate tables and reference the {@link Events#_ID}
61 * to link them with the event.</li>
62 * <li>The {@link Instances} table holds the start and end time for occurrences
63 * of an event. Each row in this table represents a single occurrence. For
64 * one-time events there will be a 1:1 mapping of instances to events. For
65 * recurring events, multiple rows will automatically be generated which
66 * correspond to multiple occurrences of that event.</li>
67 * <li>The {@link Attendees} table holds the event attendee or guest
68 * information. Each row represents a single guest of an event. It specifies the
69 * type of guest they are and their attendance response for the event.</li>
70 * <li>The {@link Reminders} table holds the alert/notification data. Each row
71 * represents a single alert for an event. An event can have multiple reminders.
72 * The number of reminders per event is specified in
73 * {@link Calendars#MAX_REMINDERS} which is set by the Sync Adapter that owns
74 * the given calendar. Reminders are specified in minutes before the event and
75 * have a type.</li>
Michael Chan73bddfc2011-10-19 18:21:49 -070076 * <li>The {@link ExtendedProperties} table holds opaque data fields used by the
RoboErik260598d2011-06-13 17:12:12 -070077 * sync adapter. The provider takes no action with items in this table except to
78 * delete them when their related events are deleted.</li>
79 * </ul>
80 * <p>
81 * Other tables include:
82 * </p>
83 * <ul>
84 * <li>
85 * {@link SyncState}, which contains free-form data maintained by the sync
86 * adapters</li>
87 * </ul>
RoboErikbec6c362011-06-14 11:06:01 -070088 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 */
RoboErikbec6c362011-06-14 11:06:01 -070090public final class CalendarContract {
RoboErikc2d53302011-06-03 09:37:58 -070091 private static final String TAG = "Calendar";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092
93 /**
RoboErikc2d53302011-06-03 09:37:58 -070094 * Broadcast Action: This is the intent that gets fired when an alarm
95 * notification needs to be posted for a reminder.
RoboErik083cd2d2011-06-30 11:53:05 -070096 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 */
RoboErik36726962011-06-14 14:01:15 -070098 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
RoboErike00d5892011-06-23 15:16:55 -070099 public static final String ACTION_EVENT_REMINDER = "android.intent.action.EVENT_REMINDER";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100
101 /**
Michael Chan37960c72012-04-19 00:18:13 -0700102 * Activity Action: Display the event to the user in the custom app as
103 * specified in {@link EventsColumns#CUSTOM_APP_PACKAGE}. The custom app
104 * will be started via {@link Activity#startActivityForResult(Intent, int)}
105 * and it should call {@link Activity#setResult(int)} with
106 * {@link Activity#RESULT_OK} or {@link Activity#RESULT_CANCELED} to
107 * acknowledge whether the action was handled or not.
Michael Chan9a9001f2012-05-14 18:27:27 -0700108 *
kmccormicke4ce5022013-04-03 14:00:19 -0700109 * The custom app should have an intent filter like the following:
Michael Chan9a9001f2012-05-14 18:27:27 -0700110 * <pre>
kmccormicke4ce5022013-04-03 14:00:19 -0700111 * &lt;intent-filter&gt;
112 * &lt;action android:name="android.provider.calendar.action.HANDLE_CUSTOM_EVENT" /&gt;
113 * &lt;category android:name="android.intent.category.DEFAULT" /&gt;
114 * &lt;data android:mimeType="vnd.android.cursor.item/event" /&gt;
115 * &lt;/intent-filter&gt;</pre>
Michael Chan37960c72012-04-19 00:18:13 -0700116 * <p>
117 * Input: {@link Intent#getData} has the event URI. The extra
118 * {@link #EXTRA_EVENT_BEGIN_TIME} has the start time of the instance. The
119 * extra {@link #EXTRA_CUSTOM_APP_URI} will have the
120 * {@link EventsColumns#CUSTOM_APP_URI}.
121 * <p>
122 * Output: {@link Activity#RESULT_OK} if this was handled; otherwise
kmccormicke4ce5022013-04-03 14:00:19 -0700123 * {@link Activity#RESULT_CANCELED}.
Michael Chan37960c72012-04-19 00:18:13 -0700124 */
125 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
126 public static final String ACTION_HANDLE_CUSTOM_EVENT =
127 "android.provider.calendar.action.HANDLE_CUSTOM_EVENT";
128
129 /**
130 * Intent Extras key: {@link EventsColumns#CUSTOM_APP_URI} for the event in
131 * the {@link #ACTION_HANDLE_CUSTOM_EVENT} intent
132 */
Michael Chanf0c4c652012-04-19 16:27:46 -0700133 public static final String EXTRA_CUSTOM_APP_URI = "customAppUri";
Michael Chan37960c72012-04-19 00:18:13 -0700134
135 /**
RoboErikc2d53302011-06-03 09:37:58 -0700136 * Intent Extras key: The start time of an event or an instance of a
137 * recurring event. (milliseconds since epoch)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 */
RoboErike00d5892011-06-23 15:16:55 -0700139 public static final String EXTRA_EVENT_BEGIN_TIME = "beginTime";
RoboErikc2d53302011-06-03 09:37:58 -0700140
141 /**
142 * Intent Extras key: The end time of an event or an instance of a recurring
143 * event. (milliseconds since epoch)
144 */
RoboErike00d5892011-06-23 15:16:55 -0700145 public static final String EXTRA_EVENT_END_TIME = "endTime";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Erike9b734d2011-02-14 13:32:19 -0800147 /**
Michael Chan7420f132011-08-25 00:54:25 -0700148 * Intent Extras key: When creating an event, set this to true to create an
149 * all-day event by default
150 */
151 public static final String EXTRA_EVENT_ALL_DAY = "allDay";
152
153 /**
RoboErikc2d53302011-06-03 09:37:58 -0700154 * This authority is used for writing to or querying from the calendar
155 * provider. Note: This is set at first run and cannot be changed without
156 * breaking apps that access the provider.
Erike9b734d2011-02-14 13:32:19 -0800157 */
Ken Shirriff1790c132010-01-22 13:45:31 -0800158 public static final String AUTHORITY = "com.android.calendar";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159
160 /**
161 * The content:// style URL for the top-level calendar authority
162 */
RoboErik083cd2d2011-06-30 11:53:05 -0700163 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
165 /**
Ken Shirriff5b387e12009-10-23 09:50:41 -0700166 * An optional insert, update or delete URI parameter that allows the caller
RoboErikc2d53302011-06-03 09:37:58 -0700167 * to specify that it is a sync adapter. The default value is false. If set
168 * to true, the modified row is not marked as "dirty" (needs to be synced)
169 * and when the provider calls
170 * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}
171 * , the third parameter "syncToNetwork" is set to false. Furthermore, if
172 * set to true, the caller must also include
Andy McFadden6f5b4552011-06-09 15:43:59 -0700173 * {@link Calendars#ACCOUNT_NAME} and {@link Calendars#ACCOUNT_TYPE} as
RoboErikc2d53302011-06-03 09:37:58 -0700174 * query parameters.
175 *
Andy McFadden6f5b4552011-06-09 15:43:59 -0700176 * @see Uri.Builder#appendQueryParameter(java.lang.String, java.lang.String)
Ken Shirriff5b387e12009-10-23 09:50:41 -0700177 */
178 public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
179
RoboErikc2d53302011-06-03 09:37:58 -0700180 /**
181 * A special account type for calendars not associated with any account.
182 * Normally calendars that do not match an account on the device will be
183 * removed. Setting the account_type on a calendar to this will prevent it
184 * from being wiped if it does not match an existing account.
185 *
186 * @see SyncColumns#ACCOUNT_TYPE
187 */
188 public static final String ACCOUNT_TYPE_LOCAL = "LOCAL";
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700189
190 /**
RoboErik36726962011-06-14 14:01:15 -0700191 * This utility class cannot be instantiated
192 */
193 private CalendarContract() {}
194
195 /**
RoboErikc2d53302011-06-03 09:37:58 -0700196 * Generic columns for use by sync adapters. The specific functions of these
197 * columns are private to the sync adapter. Other clients of the API should
198 * not attempt to either read or write this column. These columns are
199 * editable as part of the Calendars Uri, but can only be read if accessed
200 * through any other Uri.
Fabrice Di Meglio36f77842010-06-29 19:33:45 -0700201 */
RoboErikc2d53302011-06-03 09:37:58 -0700202 protected interface CalendarSyncColumns {
Fabrice Di Meglio36f77842010-06-29 19:33:45 -0700203
RoboErik9734df52011-06-09 14:11:25 -0700204
205 /**
206 * Generic column for use by sync adapters. Column name.
207 * <P>Type: TEXT</P>
208 */
RoboErikbe010392011-05-26 12:28:38 -0700209 public static final String CAL_SYNC1 = "cal_sync1";
RoboErik9734df52011-06-09 14:11:25 -0700210
211 /**
212 * Generic column for use by sync adapters. Column name.
213 * <P>Type: TEXT</P>
214 */
RoboErikbe010392011-05-26 12:28:38 -0700215 public static final String CAL_SYNC2 = "cal_sync2";
RoboErik9734df52011-06-09 14:11:25 -0700216
217 /**
218 * Generic column for use by sync adapters. Column name.
219 * <P>Type: TEXT</P>
220 */
RoboErikbe010392011-05-26 12:28:38 -0700221 public static final String CAL_SYNC3 = "cal_sync3";
RoboErik9734df52011-06-09 14:11:25 -0700222
223 /**
224 * Generic column for use by sync adapters. Column name.
225 * <P>Type: TEXT</P>
226 */
RoboErikbe010392011-05-26 12:28:38 -0700227 public static final String CAL_SYNC4 = "cal_sync4";
RoboErik9734df52011-06-09 14:11:25 -0700228
229 /**
230 * Generic column for use by sync adapters. Column name.
231 * <P>Type: TEXT</P>
232 */
RoboErikbe010392011-05-26 12:28:38 -0700233 public static final String CAL_SYNC5 = "cal_sync5";
RoboErik9734df52011-06-09 14:11:25 -0700234
235 /**
236 * Generic column for use by sync adapters. Column name.
237 * <P>Type: TEXT</P>
238 */
RoboErikbe010392011-05-26 12:28:38 -0700239 public static final String CAL_SYNC6 = "cal_sync6";
RoboErik9734df52011-06-09 14:11:25 -0700240
241 /**
242 * Generic column for use by sync adapters. Column name.
243 * <P>Type: TEXT</P>
244 */
245 public static final String CAL_SYNC7 = "cal_sync7";
246
247 /**
248 * Generic column for use by sync adapters. Column name.
249 * <P>Type: TEXT</P>
250 */
251 public static final String CAL_SYNC8 = "cal_sync8";
252
253 /**
254 * Generic column for use by sync adapters. Column name.
255 * <P>Type: TEXT</P>
256 */
257 public static final String CAL_SYNC9 = "cal_sync9";
258
259 /**
260 * Generic column for use by sync adapters. Column name.
261 * <P>Type: TEXT</P>
262 */
263 public static final String CAL_SYNC10 = "cal_sync10";
Fabrice Di Meglio36f77842010-06-29 19:33:45 -0700264 }
265
266 /**
RoboErikc2d53302011-06-03 09:37:58 -0700267 * Columns for Sync information used by Calendars and Events tables. These
268 * have specific uses which are expected to be consistent by the app and
269 * sync adapter.
270 *
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700271 */
RoboErik00258602011-06-13 13:47:59 -0700272 protected interface SyncColumns extends CalendarSyncColumns {
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700273 /**
RoboErikc2d53302011-06-03 09:37:58 -0700274 * The account that was used to sync the entry to the device. If the
275 * account_type is not {@link #ACCOUNT_TYPE_LOCAL} then the name and
276 * type must match an account on the device or the calendar will be
277 * deleted.
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700278 * <P>Type: TEXT</P>
279 */
RoboErik651c02e2011-05-05 15:14:31 -0700280 public static final String ACCOUNT_NAME = "account_name";
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700281
282 /**
RoboErikc2d53302011-06-03 09:37:58 -0700283 * The type of the account that was used to sync the entry to the
284 * device. A type of {@link #ACCOUNT_TYPE_LOCAL} will keep this event
285 * form being deleted if there are no matching accounts on the device.
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700286 * <P>Type: TEXT</P>
287 */
RoboErik651c02e2011-05-05 15:14:31 -0700288 public static final String ACCOUNT_TYPE = "account_type";
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700289
290 /**
RoboErikc2d53302011-06-03 09:37:58 -0700291 * The unique ID for a row assigned by the sync source. NULL if the row
292 * has never been synced. This is used as a reference id for exceptions
293 * along with {@link BaseColumns#_ID}.
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700294 * <P>Type: TEXT</P>
295 */
296 public static final String _SYNC_ID = "_sync_id";
297
298 /**
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700299 * Used to indicate that local, unsynced, changes are present.
300 * <P>Type: INTEGER (long)</P>
301 */
Alon Albert8ac6a632012-12-17 17:21:18 -0800302
RoboErik651c02e2011-05-05 15:14:31 -0700303 public static final String DIRTY = "dirty";
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700304
Alon Albert866f40a2011-06-06 14:04:00 -0700305 /**
Alon Albert8ac6a632012-12-17 17:21:18 -0800306 * Used in conjunction with {@link #DIRTY} to indicate what packages wrote local changes.
307 * <P>Type: TEXT</P>
308 */
309 public static final String MUTATORS = "mutators";
310
311 /**
RoboErik9734df52011-06-09 14:11:25 -0700312 * Whether the row has been deleted but not synced to the server. A
313 * deleted row should be ignored.
314 * <P>
315 * Type: INTEGER (boolean)
316 * </P>
317 */
318 public static final String DELETED = "deleted";
319
320 /**
Alon Albert866f40a2011-06-06 14:04:00 -0700321 * If set to 1 this causes events on this calendar to be duplicated with
RoboErik00258602011-06-13 13:47:59 -0700322 * {@link Events#LAST_SYNCED} set to 1 whenever the event
RoboErik9734df52011-06-09 14:11:25 -0700323 * transitions from non-dirty to dirty. The duplicated event will not be
324 * expanded in the instances table and will only show up in sync adapter
325 * queries of the events table. It will also be deleted when the
Alon Albert866f40a2011-06-06 14:04:00 -0700326 * originating event has its dirty flag cleared by the sync adapter.
327 * <P>Type: INTEGER (boolean)</P>
328 */
329 public static final String CAN_PARTIALLY_UPDATE = "canPartiallyUpdate";
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700330 }
331
332 /**
RoboErikc2d53302011-06-03 09:37:58 -0700333 * Columns specific to the Calendars Uri that other Uris can query.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 */
RoboErike00d5892011-06-23 15:16:55 -0700335 protected interface CalendarColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 /**
RoboErik4f520612011-09-19 17:47:53 -0700337 * The color of the calendar. This should only be updated by the sync
338 * adapter, not other apps, as changing a calendar's color can adversely
339 * affect its display.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 * <P>Type: INTEGER (color value)</P>
341 */
RoboErik651c02e2011-05-05 15:14:31 -0700342 public static final String CALENDAR_COLOR = "calendar_color";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343
344 /**
RoboErik4172d952011-10-25 13:59:13 -0700345 * A key for looking up a color from the {@link Colors} table. NULL or
346 * an empty string are reserved for indicating that the calendar does
347 * not use a key for looking up the color. The provider will update
348 * {@link #CALENDAR_COLOR} automatically when a valid key is written to
349 * this column. The key must reference an existing row of the
RoboErik8a8eebc2011-10-20 16:57:18 -0700350 * {@link Colors} table. @see Colors
RoboErikf8143c52011-09-28 15:16:00 -0700351 * <P>
352 * Type: TEXT
353 * </P>
RoboErikf8143c52011-09-28 15:16:00 -0700354 */
RoboErik4172d952011-10-25 13:59:13 -0700355 public static final String CALENDAR_COLOR_KEY = "calendar_color_index";
RoboErikf8143c52011-09-28 15:16:00 -0700356
357 /**
RoboErik9734df52011-06-09 14:11:25 -0700358 * The display name of the calendar. Column name.
RoboErikf8143c52011-09-28 15:16:00 -0700359 * <P>
360 * Type: TEXT
361 * </P>
RoboErik9734df52011-06-09 14:11:25 -0700362 */
363 public static final String CALENDAR_DISPLAY_NAME = "calendar_displayName";
364
365 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 * The level of access that the user has for the calendar
367 * <P>Type: INTEGER (one of the values below)</P>
368 */
RoboErik9734df52011-06-09 14:11:25 -0700369 public static final String CALENDAR_ACCESS_LEVEL = "calendar_access_level";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370
371 /** Cannot access the calendar */
RoboErik9734df52011-06-09 14:11:25 -0700372 public static final int CAL_ACCESS_NONE = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 /** Can only see free/busy information about the calendar */
RoboErik9734df52011-06-09 14:11:25 -0700374 public static final int CAL_ACCESS_FREEBUSY = 100;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 /** Can read all event details */
RoboErik9734df52011-06-09 14:11:25 -0700376 public static final int CAL_ACCESS_READ = 200;
RoboErikc2d53302011-06-03 09:37:58 -0700377 /** Can reply yes/no/maybe to an event */
RoboErik9734df52011-06-09 14:11:25 -0700378 public static final int CAL_ACCESS_RESPOND = 300;
RoboErikc2d53302011-06-03 09:37:58 -0700379 /** not used */
RoboErik9734df52011-06-09 14:11:25 -0700380 public static final int CAL_ACCESS_OVERRIDE = 400;
RoboErikc2d53302011-06-03 09:37:58 -0700381 /** Full access to modify the calendar, but not the access control
382 * settings
383 */
RoboErik9734df52011-06-09 14:11:25 -0700384 public static final int CAL_ACCESS_CONTRIBUTOR = 500;
RoboErikc2d53302011-06-03 09:37:58 -0700385 /** Full access to modify the calendar, but not the access control
386 * settings
387 */
RoboErik9734df52011-06-09 14:11:25 -0700388 public static final int CAL_ACCESS_EDITOR = 600;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 /** Full access to the calendar */
RoboErik9734df52011-06-09 14:11:25 -0700390 public static final int CAL_ACCESS_OWNER = 700;
Debajit Ghosh2dcaafd2009-09-18 18:29:37 -0700391 /** Domain admin */
RoboErik9734df52011-06-09 14:11:25 -0700392 public static final int CAL_ACCESS_ROOT = 800;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393
394 /**
395 * Is the calendar selected to be displayed?
RoboErikc2d53302011-06-03 09:37:58 -0700396 * 0 - do not show events associated with this calendar.
397 * 1 - show events associated with this calendar
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 * <P>Type: INTEGER (boolean)</P>
399 */
Andy McFaddendf2e2c82011-04-19 15:08:37 -0700400 public static final String VISIBLE = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401
402 /**
RoboErikc2d53302011-06-03 09:37:58 -0700403 * The time zone the calendar is associated with.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 * <P>Type: TEXT</P>
405 */
RoboErik9734df52011-06-09 14:11:25 -0700406 public static final String CALENDAR_TIME_ZONE = "calendar_timezone";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407
408 /**
RoboErikc2d53302011-06-03 09:37:58 -0700409 * Is this calendar synced and are its events stored on the device?
410 * 0 - Do not sync this calendar or store events for this calendar.
411 * 1 - Sync down events for this calendar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 * <p>Type: INTEGER (boolean)</p>
413 */
414 public static final String SYNC_EVENTS = "sync_events";
Ken Shirriff1d6442f2009-07-09 13:50:17 -0700415
416 /**
RoboErik9734df52011-06-09 14:11:25 -0700417 * The owner account for this calendar, based on the calendar feed.
418 * This will be different from the _SYNC_ACCOUNT for delegated calendars.
419 * Column name.
420 * <P>Type: String</P>
Ken Shirriff1d6442f2009-07-09 13:50:17 -0700421 */
RoboErik9734df52011-06-09 14:11:25 -0700422 public static final String OWNER_ACCOUNT = "ownerAccount";
Fred Quintana328c0e72009-12-07 14:52:28 -0800423
424 /**
RoboErik9734df52011-06-09 14:11:25 -0700425 * Can the organizer respond to the event? If no, the status of the
426 * organizer should not be shown by the UI. Defaults to 1. Column name.
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700427 * <P>Type: INTEGER (boolean)</P>
Fred Quintana328c0e72009-12-07 14:52:28 -0800428 */
RoboErik9734df52011-06-09 14:11:25 -0700429 public static final String CAN_ORGANIZER_RESPOND = "canOrganizerRespond";
430
431 /**
432 * Can the organizer modify the time zone of the event? Column name.
433 * <P>Type: INTEGER (boolean)</P>
434 */
435 public static final String CAN_MODIFY_TIME_ZONE = "canModifyTimeZone";
436
437 /**
438 * The maximum number of reminders allowed for an event. Column name.
439 * <P>Type: INTEGER</P>
440 */
441 public static final String MAX_REMINDERS = "maxReminders";
442
443 /**
444 * A comma separated list of reminder methods supported for this
445 * calendar in the format "#,#,#". Valid types are
446 * {@link Reminders#METHOD_DEFAULT}, {@link Reminders#METHOD_ALERT},
Alon Albertbd251612012-02-23 10:30:51 -0800447 * {@link Reminders#METHOD_EMAIL}, {@link Reminders#METHOD_SMS},
448 * {@link Reminders#METHOD_ALARM}. Column name.
RoboErik9734df52011-06-09 14:11:25 -0700449 * <P>Type: TEXT</P>
450 */
451 public static final String ALLOWED_REMINDERS = "allowedReminders";
RoboErikf8143c52011-09-28 15:16:00 -0700452
453 /**
454 * A comma separated list of availability types supported for this
455 * calendar in the format "#,#,#". Valid types are
456 * {@link Events#AVAILABILITY_BUSY}, {@link Events#AVAILABILITY_FREE},
457 * {@link Events#AVAILABILITY_TENTATIVE}. Setting this field to only
458 * {@link Events#AVAILABILITY_BUSY} should be used to indicate that
459 * changing the availability is not supported.
460 *
RoboErikf8143c52011-09-28 15:16:00 -0700461 */
462 public static final String ALLOWED_AVAILABILITY = "allowedAvailability";
463
464 /**
465 * A comma separated list of attendee types supported for this calendar
466 * in the format "#,#,#". Valid types are {@link Attendees#TYPE_NONE},
467 * {@link Attendees#TYPE_OPTIONAL}, {@link Attendees#TYPE_REQUIRED},
468 * {@link Attendees#TYPE_RESOURCE}. Setting this field to only
469 * {@link Attendees#TYPE_NONE} should be used to indicate that changing
470 * the attendee type is not supported.
471 *
RoboErikf8143c52011-09-28 15:16:00 -0700472 */
473 public static final String ALLOWED_ATTENDEE_TYPES = "allowedAttendeeTypes";
Alon Albert0a9a2192012-09-18 11:10:49 -0700474
475 /**
476 * Is this the primary calendar for this account. If this column is not explicitly set, the
477 * provider will return 1 if {@link Calendars#ACCOUNT_NAME} is equal to
478 * {@link Calendars#OWNER_ACCOUNT}.
479 */
480 public static final String IS_PRIMARY = "isPrimary";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 }
482
483 /**
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700484 * Class that represents a Calendar Entity. There is one entry per calendar.
RoboErikc2d53302011-06-03 09:37:58 -0700485 * This is a helper class to make batch operations easier.
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700486 */
RoboErik36726962011-06-14 14:01:15 -0700487 public static final class CalendarEntity implements BaseColumns, SyncColumns, CalendarColumns {
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700488
RoboErikc2d53302011-06-03 09:37:58 -0700489 /**
490 * The default Uri used when creating a new calendar EntityIterator.
491 */
492 @SuppressWarnings("hiding")
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700493 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY +
494 "/calendar_entities");
495
RoboErikc2d53302011-06-03 09:37:58 -0700496 /**
RoboErik36726962011-06-14 14:01:15 -0700497 * This utility class cannot be instantiated
498 */
499 private CalendarEntity() {}
500
501 /**
RoboErikc2d53302011-06-03 09:37:58 -0700502 * Creates an entity iterator for the given cursor. It assumes the
503 * cursor contains a calendars query.
504 *
505 * @param cursor query on {@link #CONTENT_URI}
506 * @return an EntityIterator of calendars
507 */
508 public static EntityIterator newEntityIterator(Cursor cursor) {
509 return new EntityIteratorImpl(cursor);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700510 }
511
512 private static class EntityIteratorImpl extends CursorEntityIterator {
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700513
RoboErikc2d53302011-06-03 09:37:58 -0700514 public EntityIteratorImpl(Cursor cursor) {
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700515 super(cursor);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700516 }
517
518 @Override
519 public Entity getEntityAndIncrementCursor(Cursor cursor) throws RemoteException {
520 // we expect the cursor is already at the row we need to read from
521 final long calendarId = cursor.getLong(cursor.getColumnIndexOrThrow(_ID));
522
523 // Create the content value
524 ContentValues cv = new ContentValues();
525 cv.put(_ID, calendarId);
526
RoboErik651c02e2011-05-05 15:14:31 -0700527 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ACCOUNT_NAME);
528 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ACCOUNT_TYPE);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700529
530 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, _SYNC_ID);
RoboErik651c02e2011-05-05 15:14:31 -0700531 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DIRTY);
Alon Albert8ac6a632012-12-17 17:21:18 -0800532 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, MUTATORS);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700533
RoboErik9734df52011-06-09 14:11:25 -0700534 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC1);
535 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC2);
536 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC3);
537 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC4);
538 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC5);
539 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC6);
540 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC7);
541 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC8);
542 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC9);
543 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC10);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700544
545 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, Calendars.NAME);
546 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv,
RoboErik9734df52011-06-09 14:11:25 -0700547 Calendars.CALENDAR_DISPLAY_NAME);
Alon Albert866f40a2011-06-06 14:04:00 -0700548 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv,
549 Calendars.CALENDAR_COLOR);
Alon Albert01141122013-02-07 11:50:27 -0800550 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv,
551 Calendars.CALENDAR_COLOR_KEY);
RoboErik9734df52011-06-09 14:11:25 -0700552 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, CALENDAR_ACCESS_LEVEL);
Andy McFaddendf2e2c82011-04-19 15:08:37 -0700553 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, VISIBLE);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700554 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, SYNC_EVENTS);
RoboErik651c02e2011-05-05 15:14:31 -0700555 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv,
556 Calendars.CALENDAR_LOCATION);
RoboErik9734df52011-06-09 14:11:25 -0700557 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CALENDAR_TIME_ZONE);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700558 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv,
559 Calendars.OWNER_ACCOUNT);
560 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv,
Andy McFaddendf2e2c82011-04-19 15:08:37 -0700561 Calendars.CAN_ORGANIZER_RESPOND);
562 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv,
563 Calendars.CAN_MODIFY_TIME_ZONE);
564 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv,
565 Calendars.MAX_REMINDERS);
Alon Albert866f40a2011-06-06 14:04:00 -0700566 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv,
567 Calendars.CAN_PARTIALLY_UPDATE);
RoboErik9734df52011-06-09 14:11:25 -0700568 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv,
569 Calendars.ALLOWED_REMINDERS);
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700570
571 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, DELETED);
572
573 // Create the Entity from the ContentValue
574 Entity entity = new Entity(cv);
575
576 // Set cursor to next row
577 cursor.moveToNext();
578
579 // Return the created Entity
580 return entity;
581 }
582 }
583 }
584
585 /**
RoboErikf4010c52011-06-17 11:04:26 -0700586 * Constants and helpers for the Calendars table, which contains details for
587 * individual calendars. <h3>Operations</h3> All operations can be done
588 * either as an app or as a sync adapter. To perform an operation as a sync
589 * adapter {@link #CALLER_IS_SYNCADAPTER} should be set to true and
590 * {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be set in the Uri
591 * parameters. See
592 * {@link Uri.Builder#appendQueryParameter(java.lang.String, java.lang.String)}
593 * for details on adding parameters. Sync adapters have write access to more
594 * columns but are restricted to a single account at a time. Calendars are
595 * designed to be primarily managed by a sync adapter and inserting new
596 * calendars should be done as a sync adapter. For the most part, apps
597 * should only update calendars (such as changing the color or display
598 * name). If a local calendar is required an app can do so by inserting as a
599 * sync adapter and using an {@link #ACCOUNT_TYPE} of
600 * {@link #ACCOUNT_TYPE_LOCAL} .
601 * <dl>
602 * <dt><b>Insert</b></dt>
603 * <dd>When inserting a new calendar the following fields must be included:
604 * <ul>
605 * <li>{@link #ACCOUNT_NAME}</li>
606 * <li>{@link #ACCOUNT_TYPE}</li>
607 * <li>{@link #NAME}</li>
608 * <li>{@link #CALENDAR_DISPLAY_NAME}</li>
609 * <li>{@link #CALENDAR_COLOR}</li>
610 * <li>{@link #CALENDAR_ACCESS_LEVEL}</li>
611 * <li>{@link #OWNER_ACCOUNT}</li>
612 * </ul>
613 * The following fields are not required when inserting a Calendar but are
614 * generally a good idea to include:
615 * <ul>
616 * <li>{@link #SYNC_EVENTS} set to 1</li>
RoboErikf92ccfb2011-06-17 15:24:02 -0700617 * <li>{@link #CALENDAR_TIME_ZONE}</li>
RoboErikf4010c52011-06-17 11:04:26 -0700618 * <li>{@link #ALLOWED_REMINDERS}</li>
RoboErik4172d952011-10-25 13:59:13 -0700619 * <li>{@link #ALLOWED_AVAILABILITY}</li>
620 * <li>{@link #ALLOWED_ATTENDEE_TYPES}</li>
RoboErikf4010c52011-06-17 11:04:26 -0700621 * </ul>
622 * <dt><b>Update</b></dt>
623 * <dd>To perform an update on a calendar the {@link #_ID} of the calendar
624 * should be provided either as an appended id to the Uri (
625 * {@link ContentUris#withAppendedId}) or as the first selection item--the
626 * selection should start with "_id=?" and the first selectionArg should be
627 * the _id of the calendar. Calendars may also be updated using a selection
628 * without the id. In general, the {@link #ACCOUNT_NAME} and
629 * {@link #ACCOUNT_TYPE} should not be changed after a calendar is created
630 * as this can cause issues for sync adapters.
631 * <dt><b>Delete</b></dt>
632 * <dd>Calendars can be deleted either by the {@link #_ID} as an appended id
633 * on the Uri or using any standard selection. Deleting a calendar should
634 * generally be handled by a sync adapter as it will remove the calendar
635 * from the database and all associated data (aka events).</dd>
636 * <dt><b>Query</b></dt>
637 * <dd>Querying the Calendars table will get you all information about a set
638 * of calendars. There will be one row returned for each calendar that
639 * matches the query selection, or at most a single row if the {@link #_ID}
640 * is appended to the Uri.</dd>
641 * </dl>
642 * <h3>Calendar Columns</h3> The following Calendar columns are writable by
643 * both an app and a sync adapter.
644 * <ul>
645 * <li>{@link #NAME}</li>
646 * <li>{@link #CALENDAR_DISPLAY_NAME}</li>
RoboErikf4010c52011-06-17 11:04:26 -0700647 * <li>{@link #VISIBLE}</li>
648 * <li>{@link #SYNC_EVENTS}</li>
649 * </ul>
650 * The following Calendars columns are writable only by a sync adapter
651 * <ul>
652 * <li>{@link #ACCOUNT_NAME}</li>
653 * <li>{@link #ACCOUNT_TYPE}</li>
RoboErik4f520612011-09-19 17:47:53 -0700654 * <li>{@link #CALENDAR_COLOR}</li>
RoboErikf4010c52011-06-17 11:04:26 -0700655 * <li>{@link #_SYNC_ID}</li>
656 * <li>{@link #DIRTY}</li>
Alon Albert8ac6a632012-12-17 17:21:18 -0800657 * <li>{@link #MUTATORS}</li>
RoboErikf4010c52011-06-17 11:04:26 -0700658 * <li>{@link #OWNER_ACCOUNT}</li>
659 * <li>{@link #MAX_REMINDERS}</li>
660 * <li>{@link #ALLOWED_REMINDERS}</li>
RoboErik4172d952011-10-25 13:59:13 -0700661 * <li>{@link #ALLOWED_AVAILABILITY}</li>
662 * <li>{@link #ALLOWED_ATTENDEE_TYPES}</li>
RoboErikf4010c52011-06-17 11:04:26 -0700663 * <li>{@link #CAN_MODIFY_TIME_ZONE}</li>
664 * <li>{@link #CAN_ORGANIZER_RESPOND}</li>
665 * <li>{@link #CAN_PARTIALLY_UPDATE}</li>
666 * <li>{@link #CALENDAR_LOCATION}</li>
667 * <li>{@link #CALENDAR_TIME_ZONE}</li>
668 * <li>{@link #CALENDAR_ACCESS_LEVEL}</li>
669 * <li>{@link #DELETED}</li>
670 * <li>{@link #CAL_SYNC1}</li>
671 * <li>{@link #CAL_SYNC2}</li>
672 * <li>{@link #CAL_SYNC3}</li>
673 * <li>{@link #CAL_SYNC4}</li>
674 * <li>{@link #CAL_SYNC5}</li>
675 * <li>{@link #CAL_SYNC6}</li>
676 * <li>{@link #CAL_SYNC7}</li>
677 * <li>{@link #CAL_SYNC8}</li>
678 * <li>{@link #CAL_SYNC9}</li>
679 * <li>{@link #CAL_SYNC10}</li>
680 * </ul>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 */
RoboErik36726962011-06-14 14:01:15 -0700682 public static final class Calendars implements BaseColumns, SyncColumns, CalendarColumns {
683
684 /**
685 * This utility class cannot be instantiated
686 */
687 private Calendars() {}
688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 /**
RoboErikc2d53302011-06-03 09:37:58 -0700690 * The content:// style URL for accessing Calendars
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 */
RoboErikc2d53302011-06-03 09:37:58 -0700692 @SuppressWarnings("hiding")
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -0800693 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/calendars");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 /**
696 * The default sort order for this table
697 */
Michael Chane5e02502011-09-01 10:46:14 -0700698 public static final String DEFAULT_SORT_ORDER = CALENDAR_DISPLAY_NAME;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699
700 /**
RoboErikc2d53302011-06-03 09:37:58 -0700701 * The name of the calendar. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 * <P>Type: TEXT</P>
703 */
704 public static final String NAME = "name";
705
706 /**
RoboErikc2d53302011-06-03 09:37:58 -0700707 * The default location for the calendar. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 * <P>Type: TEXT</P>
709 */
RoboErik651c02e2011-05-05 15:14:31 -0700710 public static final String CALENDAR_LOCATION = "calendar_location";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711
712 /**
RoboErik6efb30f2011-05-05 10:11:47 -0700713 * These fields are only writable by a sync adapter. To modify them the
RoboErikc2d53302011-06-03 09:37:58 -0700714 * caller must include {@link #CALLER_IS_SYNCADAPTER},
RoboErik9734df52011-06-09 14:11:25 -0700715 * {@link #ACCOUNT_NAME}, and {@link #ACCOUNT_TYPE} in the Uri's query
RoboErik083cd2d2011-06-30 11:53:05 -0700716 * parameters. TODO move to provider
717 *
718 * @hide
RoboErik6efb30f2011-05-05 10:11:47 -0700719 */
720 public static final String[] SYNC_WRITABLE_COLUMNS = new String[] {
RoboErik651c02e2011-05-05 15:14:31 -0700721 ACCOUNT_NAME,
722 ACCOUNT_TYPE,
RoboErik6efb30f2011-05-05 10:11:47 -0700723 _SYNC_ID,
RoboErik651c02e2011-05-05 15:14:31 -0700724 DIRTY,
Alon Albert8ac6a632012-12-17 17:21:18 -0800725 MUTATORS,
RoboErik6efb30f2011-05-05 10:11:47 -0700726 OWNER_ACCOUNT,
727 MAX_REMINDERS,
RoboErikf4010c52011-06-17 11:04:26 -0700728 ALLOWED_REMINDERS,
RoboErik6efb30f2011-05-05 10:11:47 -0700729 CAN_MODIFY_TIME_ZONE,
730 CAN_ORGANIZER_RESPOND,
Alon Albert866f40a2011-06-06 14:04:00 -0700731 CAN_PARTIALLY_UPDATE,
RoboErik651c02e2011-05-05 15:14:31 -0700732 CALENDAR_LOCATION,
RoboErik9734df52011-06-09 14:11:25 -0700733 CALENDAR_TIME_ZONE,
734 CALENDAR_ACCESS_LEVEL,
RoboErik6efb30f2011-05-05 10:11:47 -0700735 DELETED,
RoboErikbe010392011-05-26 12:28:38 -0700736 CAL_SYNC1,
737 CAL_SYNC2,
738 CAL_SYNC3,
739 CAL_SYNC4,
RoboErikc2d53302011-06-03 09:37:58 -0700740 CAL_SYNC5,
741 CAL_SYNC6,
RoboErik9734df52011-06-09 14:11:25 -0700742 CAL_SYNC7,
743 CAL_SYNC8,
744 CAL_SYNC9,
745 CAL_SYNC10,
RoboErik6efb30f2011-05-05 10:11:47 -0700746 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 }
748
Fabrice Di Meglioc3cc1332010-05-21 20:01:52 -0700749 /**
750 * Columns from the Attendees table that other tables join into themselves.
751 */
RoboErikb2c75602011-06-13 12:53:48 -0700752 protected interface AttendeesColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753
754 /**
RoboErikc2d53302011-06-03 09:37:58 -0700755 * The id of the event. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 * <P>Type: INTEGER</P>
757 */
758 public static final String EVENT_ID = "event_id";
759
760 /**
RoboErikc2d53302011-06-03 09:37:58 -0700761 * The name of the attendee. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 * <P>Type: STRING</P>
763 */
764 public static final String ATTENDEE_NAME = "attendeeName";
765
766 /**
RoboErikc2d53302011-06-03 09:37:58 -0700767 * The email address of the attendee. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 * <P>Type: STRING</P>
769 */
770 public static final String ATTENDEE_EMAIL = "attendeeEmail";
771
772 /**
RoboErikc2d53302011-06-03 09:37:58 -0700773 * The relationship of the attendee to the user. Column name.
774 * <P>Type: INTEGER (one of {@link #RELATIONSHIP_ATTENDEE}, ...}.</P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 */
776 public static final String ATTENDEE_RELATIONSHIP = "attendeeRelationship";
777
778 public static final int RELATIONSHIP_NONE = 0;
779 public static final int RELATIONSHIP_ATTENDEE = 1;
780 public static final int RELATIONSHIP_ORGANIZER = 2;
781 public static final int RELATIONSHIP_PERFORMER = 3;
782 public static final int RELATIONSHIP_SPEAKER = 4;
783
784 /**
RoboErikc2d53302011-06-03 09:37:58 -0700785 * The type of attendee. Column name.
RoboErikf8143c52011-09-28 15:16:00 -0700786 * <P>
RoboErik4172d952011-10-25 13:59:13 -0700787 * Type: Integer (one of {@link #TYPE_NONE}, {@link #TYPE_REQUIRED},
788 * {@link #TYPE_OPTIONAL}, {@link #TYPE_RESOURCE})
RoboErikf8143c52011-09-28 15:16:00 -0700789 * </P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 */
791 public static final String ATTENDEE_TYPE = "attendeeType";
792
793 public static final int TYPE_NONE = 0;
794 public static final int TYPE_REQUIRED = 1;
795 public static final int TYPE_OPTIONAL = 2;
RoboErikf8143c52011-09-28 15:16:00 -0700796 /**
RoboErik4172d952011-10-25 13:59:13 -0700797 * This specifies that an attendee is a resource, like a room, a
798 * cabbage, or something and not an actual person.
RoboErikf8143c52011-09-28 15:16:00 -0700799 */
800 public static final int TYPE_RESOURCE = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801
802 /**
RoboErikc2d53302011-06-03 09:37:58 -0700803 * The attendance status of the attendee. Column name.
804 * <P>Type: Integer (one of {@link #ATTENDEE_STATUS_ACCEPTED}, ...).</P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 */
806 public static final String ATTENDEE_STATUS = "attendeeStatus";
807
808 public static final int ATTENDEE_STATUS_NONE = 0;
809 public static final int ATTENDEE_STATUS_ACCEPTED = 1;
810 public static final int ATTENDEE_STATUS_DECLINED = 2;
811 public static final int ATTENDEE_STATUS_INVITED = 3;
812 public static final int ATTENDEE_STATUS_TENTATIVE = 4;
Michael Chan48ec6222012-04-17 15:58:28 -0700813
814 /**
815 * The identity of the attendee as referenced in
816 * {@link ContactsContract.CommonDataKinds.Identity#IDENTITY}.
Michael Chan37f1d292012-04-17 18:40:51 -0700817 * This is required only if {@link #ATTENDEE_ID_NAMESPACE} is present. Column name.
Michael Chan48ec6222012-04-17 15:58:28 -0700818 * <P>Type: STRING</P>
Michael Chan48ec6222012-04-17 15:58:28 -0700819 */
820 public static final String ATTENDEE_IDENTITY = "attendeeIdentity";
821
822 /**
823 * The identity name space of the attendee as referenced in
824 * {@link ContactsContract.CommonDataKinds.Identity#NAMESPACE}.
Michael Chan37f1d292012-04-17 18:40:51 -0700825 * This is required only if {@link #ATTENDEE_IDENTITY} is present. Column name.
Michael Chan48ec6222012-04-17 15:58:28 -0700826 * <P>Type: STRING</P>
Michael Chan48ec6222012-04-17 15:58:28 -0700827 */
828 public static final String ATTENDEE_ID_NAMESPACE = "attendeeIdNamespace";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 }
830
RoboErikc2d53302011-06-03 09:37:58 -0700831 /**
RoboErik3771fcb2011-06-16 15:41:31 -0700832 * Fields and helpers for interacting with Attendees. Each row of this table
833 * represents a single attendee or guest of an event. Calling
RoboErik58644022011-07-08 13:39:05 -0700834 * {@link #query(ContentResolver, long, String[])} will return a list of attendees for
RoboErik3771fcb2011-06-16 15:41:31 -0700835 * the event with the given eventId. Both apps and sync adapters may write
836 * to this table. There are six writable fields and all of them except
837 * {@link #ATTENDEE_NAME} must be included when inserting a new attendee.
838 * They are:
839 * <ul>
840 * <li>{@link #EVENT_ID}</li>
841 * <li>{@link #ATTENDEE_NAME}</li>
842 * <li>{@link #ATTENDEE_EMAIL}</li>
843 * <li>{@link #ATTENDEE_RELATIONSHIP}</li>
844 * <li>{@link #ATTENDEE_TYPE}</li>
845 * <li>{@link #ATTENDEE_STATUS}</li>
Michael Chan48ec6222012-04-17 15:58:28 -0700846 * <li>{@link #ATTENDEE_IDENTITY}</li>
847 * <li>{@link #ATTENDEE_ID_NAMESPACE}</li>
RoboErik3771fcb2011-06-16 15:41:31 -0700848 * </ul>
RoboErikc2d53302011-06-03 09:37:58 -0700849 */
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -0800850 public static final class Attendees implements BaseColumns, AttendeesColumns, EventsColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851
RoboErikc2d53302011-06-03 09:37:58 -0700852 /**
853 * The content:// style URL for accessing Attendees data
854 */
855 @SuppressWarnings("hiding")
856 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/attendees");
RoboErikc2d53302011-06-03 09:37:58 -0700857 private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=?";
858
859 /**
RoboErik36726962011-06-14 14:01:15 -0700860 * This utility class cannot be instantiated
861 */
862 private Attendees() {}
863
864 /**
RoboErikc2d53302011-06-03 09:37:58 -0700865 * Queries all attendees associated with the given event. This is a
866 * blocking call and should not be done on the UI thread.
RoboErik36726962011-06-14 14:01:15 -0700867 *
RoboErikc2d53302011-06-03 09:37:58 -0700868 * @param cr The content resolver to use for the query
869 * @param eventId The id of the event to retrieve attendees for
RoboErik58644022011-07-08 13:39:05 -0700870 * @param projection the columns to return in the cursor
RoboErikc2d53302011-06-03 09:37:58 -0700871 * @return A Cursor containing all attendees for the event
872 */
RoboErik58644022011-07-08 13:39:05 -0700873 public static final Cursor query(ContentResolver cr, long eventId, String[] projection) {
RoboErikc2d53302011-06-03 09:37:58 -0700874 String[] attArgs = {Long.toString(eventId)};
RoboErik58644022011-07-08 13:39:05 -0700875 return cr.query(CONTENT_URI, projection, ATTENDEES_WHERE, attArgs /* selection args */,
RoboErikc2d53302011-06-03 09:37:58 -0700876 null /* sort order */);
877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 }
879
880 /**
881 * Columns from the Events table that other tables join into themselves.
882 */
RoboErikb2c75602011-06-13 12:53:48 -0700883 protected interface EventsColumns {
Andy McFaddendf2e2c82011-04-19 15:08:37 -0700884
885 /**
RoboErikc2d53302011-06-03 09:37:58 -0700886 * The {@link Calendars#_ID} of the calendar the event belongs to.
887 * Column name.
888 * <P>Type: INTEGER</P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 */
890 public static final String CALENDAR_ID = "calendar_id";
891
892 /**
RoboErikc2d53302011-06-03 09:37:58 -0700893 * The title of the event. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 * <P>Type: TEXT</P>
895 */
896 public static final String TITLE = "title";
897
898 /**
RoboErikc2d53302011-06-03 09:37:58 -0700899 * The description of the event. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 * <P>Type: TEXT</P>
901 */
902 public static final String DESCRIPTION = "description";
903
904 /**
RoboErikc2d53302011-06-03 09:37:58 -0700905 * Where the event takes place. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 * <P>Type: TEXT</P>
907 */
908 public static final String EVENT_LOCATION = "eventLocation";
909
910 /**
RoboErikf8143c52011-09-28 15:16:00 -0700911 * A secondary color for the individual event. This should only be
912 * updated by the sync adapter for a given account.
RoboErik9734df52011-06-09 14:11:25 -0700913 * <P>Type: INTEGER</P>
914 */
915 public static final String EVENT_COLOR = "eventColor";
916
917 /**
RoboErik4172d952011-10-25 13:59:13 -0700918 * A secondary color key for the individual event. NULL or an empty
919 * string are reserved for indicating that the event does not use a key
920 * for looking up the color. The provider will update
921 * {@link #EVENT_COLOR} automatically when a valid key is written to
922 * this column. The key must reference an existing row of the
RoboErik8a8eebc2011-10-20 16:57:18 -0700923 * {@link Colors} table. @see Colors
924 * <P>
925 * Type: TEXT
926 * </P>
RoboErikf8143c52011-09-28 15:16:00 -0700927 */
RoboErik4172d952011-10-25 13:59:13 -0700928 public static final String EVENT_COLOR_KEY = "eventColor_index";
RoboErikf8143c52011-09-28 15:16:00 -0700929
930 /**
Alon Albertdc927302012-03-01 16:05:55 -0800931 * This will be {@link #EVENT_COLOR} if it is not null; otherwise, this will be
932 * {@link Calendars#CALENDAR_COLOR}.
933 * Read-only value. To modify, write to {@link #EVENT_COLOR} or
934 * {@link Calendars#CALENDAR_COLOR} directly.
935 *<P>
936 * Type: INTEGER
937 *</P>
938 */
939 public static final String DISPLAY_COLOR = "displayColor";
940
941 /**
RoboErikc2d53302011-06-03 09:37:58 -0700942 * The event status. Column name.
943 * <P>Type: INTEGER (one of {@link #STATUS_TENTATIVE}...)</P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 */
945 public static final String STATUS = "eventStatus";
946
947 public static final int STATUS_TENTATIVE = 0;
948 public static final int STATUS_CONFIRMED = 1;
949 public static final int STATUS_CANCELED = 2;
950
951 /**
952 * This is a copy of the attendee status for the owner of this event.
953 * This field is copied here so that we can efficiently filter out
954 * events that are declined without having to look in the Attendees
RoboErikc2d53302011-06-03 09:37:58 -0700955 * table. Column name.
Ken Shirriff5b387e12009-10-23 09:50:41 -0700956 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 * <P>Type: INTEGER (int)</P>
958 */
959 public static final String SELF_ATTENDEE_STATUS = "selfAttendeeStatus";
Ken Shirriff5b387e12009-10-23 09:50:41 -0700960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 /**
RoboErikc2d53302011-06-03 09:37:58 -0700962 * This column is available for use by sync adapters. Column name.
Marc Blank64a556d2010-02-25 12:53:16 -0800963 * <P>Type: TEXT</P>
964 */
RoboErik651c02e2011-05-05 15:14:31 -0700965 public static final String SYNC_DATA1 = "sync_data1";
Marc Blank64a556d2010-02-25 12:53:16 -0800966
967 /**
RoboErik9734df52011-06-09 14:11:25 -0700968 * This column is available for use by sync adapters. Column name.
969 * <P>Type: TEXT</P>
970 */
971 public static final String SYNC_DATA2 = "sync_data2";
972
973 /**
974 * This column is available for use by sync adapters. Column name.
975 * <P>Type: TEXT</P>
976 */
977 public static final String SYNC_DATA3 = "sync_data3";
978
979 /**
980 * This column is available for use by sync adapters. Column name.
981 * <P>Type: TEXT</P>
982 */
983 public static final String SYNC_DATA4 = "sync_data4";
984
985 /**
986 * This column is available for use by sync adapters. Column name.
987 * <P>Type: TEXT</P>
988 */
989 public static final String SYNC_DATA5 = "sync_data5";
990
991 /**
992 * This column is available for use by sync adapters. Column name.
993 * <P>Type: TEXT</P>
994 */
995 public static final String SYNC_DATA6 = "sync_data6";
996
997 /**
998 * This column is available for use by sync adapters. Column name.
Alon Albert866f40a2011-06-06 14:04:00 -0700999 * <P>Type: TEXT</P>
1000 */
1001 public static final String SYNC_DATA7 = "sync_data7";
1002
1003 /**
RoboErik9734df52011-06-09 14:11:25 -07001004 * This column is available for use by sync adapters. Column name.
1005 * <P>Type: TEXT</P>
1006 */
1007 public static final String SYNC_DATA8 = "sync_data8";
1008
1009 /**
1010 * This column is available for use by sync adapters. Column name.
1011 * <P>Type: TEXT</P>
1012 */
1013 public static final String SYNC_DATA9 = "sync_data9";
1014
1015 /**
1016 * This column is available for use by sync adapters. Column name.
1017 * <P>Type: TEXT</P>
1018 */
1019 public static final String SYNC_DATA10 = "sync_data10";
1020
1021 /**
Alon Albert866f40a2011-06-06 14:04:00 -07001022 * Used to indicate that a row is not a real event but an original copy of a locally
1023 * modified event. A copy is made when an event changes from non-dirty to dirty and the
1024 * event is on a calendar with {@link Calendars#CAN_PARTIALLY_UPDATE} set to 1. This copy
1025 * does not get expanded in the instances table and is only visible in queries made by a
1026 * sync adapter. The copy gets removed when the event is changed back to non-dirty by a
1027 * sync adapter.
1028 * <P>Type: INTEGER (boolean)</P>
1029 */
1030 public static final String LAST_SYNCED = "lastSynced";
1031
1032 /**
RoboErikc2d53302011-06-03 09:37:58 -07001033 * The time the event starts in UTC millis since epoch. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 * <P>Type: INTEGER (long; millis since epoch)</P>
1035 */
1036 public static final String DTSTART = "dtstart";
1037
1038 /**
RoboErikc2d53302011-06-03 09:37:58 -07001039 * The time the event ends in UTC millis since epoch. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001040 * <P>Type: INTEGER (long; millis since epoch)</P>
1041 */
1042 public static final String DTEND = "dtend";
1043
1044 /**
RoboErikc2d53302011-06-03 09:37:58 -07001045 * The duration of the event in RFC2445 format. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 * <P>Type: TEXT (duration in RFC2445 format)</P>
1047 */
1048 public static final String DURATION = "duration";
1049
1050 /**
RoboErikc2d53302011-06-03 09:37:58 -07001051 * The timezone for the event. Column name.
1052 * <P>Type: TEXT</P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 */
1054 public static final String EVENT_TIMEZONE = "eventTimezone";
1055
1056 /**
RoboErikc2d53302011-06-03 09:37:58 -07001057 * The timezone for the end time of the event. Column name.
1058 * <P>Type: TEXT</P>
Erikc07b06f2010-05-03 11:37:31 -07001059 */
RoboErik651c02e2011-05-05 15:14:31 -07001060 public static final String EVENT_END_TIMEZONE = "eventEndTimezone";
Erikc07b06f2010-05-03 11:37:31 -07001061
1062 /**
RoboErikc2d53302011-06-03 09:37:58 -07001063 * Is the event all day (time zone independent). Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 * <P>Type: INTEGER (boolean)</P>
1065 */
1066 public static final String ALL_DAY = "allDay";
1067
1068 /**
RoboErik651c02e2011-05-05 15:14:31 -07001069 * Defines how the event shows up for others when the calendar is
RoboErikc2d53302011-06-03 09:37:58 -07001070 * shared. Column name.
1071 * <P>Type: INTEGER (One of {@link #ACCESS_DEFAULT}, ...)</P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 */
RoboErik651c02e2011-05-05 15:14:31 -07001073 public static final String ACCESS_LEVEL = "accessLevel";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074
1075 /**
RoboErik651c02e2011-05-05 15:14:31 -07001076 * Default access is controlled by the server and will be treated as
1077 * public on the device.
1078 */
1079 public static final int ACCESS_DEFAULT = 0;
1080 /**
1081 * Confidential is not used by the app.
1082 */
1083 public static final int ACCESS_CONFIDENTIAL = 1;
1084 /**
RoboErikc2d53302011-06-03 09:37:58 -07001085 * Private shares the event as a free/busy slot with no details.
RoboErik651c02e2011-05-05 15:14:31 -07001086 */
1087 public static final int ACCESS_PRIVATE = 2;
1088 /**
RoboErikc2d53302011-06-03 09:37:58 -07001089 * Public makes the contents visible to anyone with access to the
RoboErik651c02e2011-05-05 15:14:31 -07001090 * calendar.
1091 */
1092 public static final int ACCESS_PUBLIC = 3;
1093
1094 /**
1095 * If this event counts as busy time or is still free time that can be
RoboErikc2d53302011-06-03 09:37:58 -07001096 * scheduled over. Column name.
RoboErik4172d952011-10-25 13:59:13 -07001097 * <P>
1098 * Type: INTEGER (One of {@link #AVAILABILITY_BUSY},
1099 * {@link #AVAILABILITY_FREE}, {@link #AVAILABILITY_TENTATIVE})
1100 * </P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 */
RoboErik651c02e2011-05-05 15:14:31 -07001102 public static final String AVAILABILITY = "availability";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103
RoboErik651c02e2011-05-05 15:14:31 -07001104 /**
1105 * Indicates that this event takes up time and will conflict with other
1106 * events.
1107 */
1108 public static final int AVAILABILITY_BUSY = 0;
1109 /**
1110 * Indicates that this event is free time and will not conflict with
1111 * other events.
1112 */
1113 public static final int AVAILABILITY_FREE = 1;
RoboErikf8143c52011-09-28 15:16:00 -07001114 /**
1115 * Indicates that the owner's availability may change, but should be
1116 * considered busy time that will conflict.
RoboErikf8143c52011-09-28 15:16:00 -07001117 */
1118 public static final int AVAILABILITY_TENTATIVE = 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119
1120 /**
RoboErikc2d53302011-06-03 09:37:58 -07001121 * Whether the event has an alarm or not. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 * <P>Type: INTEGER (boolean)</P>
1123 */
1124 public static final String HAS_ALARM = "hasAlarm";
1125
1126 /**
RoboErikc2d53302011-06-03 09:37:58 -07001127 * Whether the event has extended properties or not. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 * <P>Type: INTEGER (boolean)</P>
1129 */
1130 public static final String HAS_EXTENDED_PROPERTIES = "hasExtendedProperties";
1131
1132 /**
RoboErikc2d53302011-06-03 09:37:58 -07001133 * The recurrence rule for the event. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 * <P>Type: TEXT</P>
1135 */
1136 public static final String RRULE = "rrule";
1137
1138 /**
RoboErikc2d53302011-06-03 09:37:58 -07001139 * The recurrence dates for the event. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 * <P>Type: TEXT</P>
1141 */
1142 public static final String RDATE = "rdate";
1143
1144 /**
RoboErikc2d53302011-06-03 09:37:58 -07001145 * The recurrence exception rule for the event. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 * <P>Type: TEXT</P>
1147 */
1148 public static final String EXRULE = "exrule";
1149
1150 /**
RoboErikc2d53302011-06-03 09:37:58 -07001151 * The recurrence exception dates for the event. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 * <P>Type: TEXT</P>
1153 */
1154 public static final String EXDATE = "exdate";
1155
1156 /**
RoboErikc2d53302011-06-03 09:37:58 -07001157 * The {@link Events#_ID} of the original recurring event for which this
1158 * event is an exception. Column name.
RoboErikc0bd9bc2011-05-13 17:54:24 -07001159 * <P>Type: TEXT</P>
1160 */
1161 public static final String ORIGINAL_ID = "original_id";
1162
1163 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001164 * The _sync_id of the original recurring event for which this event is
RoboErikc0bd9bc2011-05-13 17:54:24 -07001165 * an exception. The provider should keep the original_id in sync when
RoboErikc2d53302011-06-03 09:37:58 -07001166 * this is updated. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 * <P>Type: TEXT</P>
1168 */
RoboErik651c02e2011-05-05 15:14:31 -07001169 public static final String ORIGINAL_SYNC_ID = "original_sync_id";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170
1171 /**
1172 * The original instance time of the recurring event for which this
RoboErikc2d53302011-06-03 09:37:58 -07001173 * event is an exception. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 * <P>Type: INTEGER (long; millis since epoch)</P>
1175 */
1176 public static final String ORIGINAL_INSTANCE_TIME = "originalInstanceTime";
1177
1178 /**
1179 * The allDay status (true or false) of the original recurring event
RoboErikc2d53302011-06-03 09:37:58 -07001180 * for which this event is an exception. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181 * <P>Type: INTEGER (boolean)</P>
1182 */
1183 public static final String ORIGINAL_ALL_DAY = "originalAllDay";
1184
1185 /**
RoboErikc2d53302011-06-03 09:37:58 -07001186 * The last date this event repeats on, or NULL if it never ends. Column
1187 * name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 * <P>Type: INTEGER (long; millis since epoch)</P>
1189 */
1190 public static final String LAST_DATE = "lastDate";
Ken Shirriff79f0c562009-08-05 13:29:42 -07001191
1192 /**
1193 * Whether the event has attendee information. True if the event
1194 * has full attendee data, false if the event has information about
RoboErikc2d53302011-06-03 09:37:58 -07001195 * self only. Column name.
Ken Shirriff79f0c562009-08-05 13:29:42 -07001196 * <P>Type: INTEGER (boolean)</P>
1197 */
1198 public static final String HAS_ATTENDEE_DATA = "hasAttendeeData";
Ken Shirriff3d037072009-08-17 15:43:21 -07001199
1200 /**
RoboErikc2d53302011-06-03 09:37:58 -07001201 * Whether guests can modify the event. Column name.
Ken Shirriff3d037072009-08-17 15:43:21 -07001202 * <P>Type: INTEGER (boolean)</P>
1203 */
1204 public static final String GUESTS_CAN_MODIFY = "guestsCanModify";
1205
1206 /**
RoboErikc2d53302011-06-03 09:37:58 -07001207 * Whether guests can invite other guests. Column name.
Ken Shirriff3d037072009-08-17 15:43:21 -07001208 * <P>Type: INTEGER (boolean)</P>
1209 */
1210 public static final String GUESTS_CAN_INVITE_OTHERS = "guestsCanInviteOthers";
1211
1212 /**
RoboErikc2d53302011-06-03 09:37:58 -07001213 * Whether guests can see the list of attendees. Column name.
Ken Shirriff3d037072009-08-17 15:43:21 -07001214 * <P>Type: INTEGER (boolean)</P>
1215 */
1216 public static final String GUESTS_CAN_SEE_GUESTS = "guestsCanSeeGuests";
1217
1218 /**
RoboErikc2d53302011-06-03 09:37:58 -07001219 * Email of the organizer (owner) of the event. Column name.
Ken Shirriff3d037072009-08-17 15:43:21 -07001220 * <P>Type: STRING</P>
1221 */
1222 public static final String ORGANIZER = "organizer";
1223
1224 /**
Alon Albert0a9a2192012-09-18 11:10:49 -07001225 * Are we the organizer of this event. If this column is not explicitly set, the provider
1226 * will return 1 if {@link #ORGANIZER} is equal to {@link Calendars#OWNER_ACCOUNT}.
1227 * Column name.
1228 * <P>Type: STRING</P>
1229 */
1230 public static final String IS_ORGANIZER = "isOrganizer";
1231
1232 /**
RoboErikc2d53302011-06-03 09:37:58 -07001233 * Whether the user can invite others to the event. The
1234 * GUESTS_CAN_INVITE_OTHERS is a setting that applies to an arbitrary
1235 * guest, while CAN_INVITE_OTHERS indicates if the user can invite
1236 * others (either through GUESTS_CAN_INVITE_OTHERS or because the user
1237 * has modify access to the event). Column name.
Ken Shirriff3d037072009-08-17 15:43:21 -07001238 * <P>Type: INTEGER (boolean, readonly)</P>
1239 */
1240 public static final String CAN_INVITE_OTHERS = "canInviteOthers";
Michael Chan37960c72012-04-19 00:18:13 -07001241
1242 /**
1243 * The package name of the custom app that can provide a richer
1244 * experience for the event. See the ACTION TYPE
1245 * {@link CalendarContract#ACTION_HANDLE_CUSTOM_EVENT} for details.
1246 * Column name.
1247 * <P> Type: TEXT </P>
1248 */
1249 public static final String CUSTOM_APP_PACKAGE = "customAppPackage";
1250
1251 /**
1252 * The URI used by the custom app for the event. Column name.
1253 * <P>Type: TEXT</P>
1254 */
1255 public static final String CUSTOM_APP_URI = "customAppUri";
1256
Sara Ting4d6f90e2012-09-17 11:17:15 -07001257 /**
1258 * The UID for events added from the RFC 2445 iCalendar format.
1259 * Column name.
1260 * <P>Type: TEXT</P>
1261 */
1262 public static final String UID_2445 = "uid2445";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 }
1264
1265 /**
RoboErikc2d53302011-06-03 09:37:58 -07001266 * Class that represents an Event Entity. There is one entry per event.
1267 * Recurring events show up as a single entry. This is a helper class to
1268 * make batch operations easier. A {@link ContentResolver} or
1269 * {@link ContentProviderClient} is required as the helper does additional
1270 * queries to add reminders and attendees to each entry.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 */
RoboErik651c02e2011-05-05 15:14:31 -07001272 public static final class EventsEntity implements BaseColumns, SyncColumns, EventsColumns {
Fred Quintana328c0e72009-12-07 14:52:28 -08001273 /**
1274 * The content:// style URL for this table
1275 */
Ken Shirriffa69a23b2010-01-21 17:32:39 -08001276 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY +
1277 "/event_entities");
Fred Quintana328c0e72009-12-07 14:52:28 -08001278
RoboErikc2d53302011-06-03 09:37:58 -07001279 /**
RoboErik36726962011-06-14 14:01:15 -07001280 * This utility class cannot be instantiated
1281 */
1282 private EventsEntity() {}
1283
1284 /**
RoboErikc2d53302011-06-03 09:37:58 -07001285 * Creates a new iterator for events
1286 *
1287 * @param cursor An event query
1288 * @param resolver For performing additional queries
1289 * @return an EntityIterator containing one entity per event in the
1290 * cursor
1291 */
Fred Quintana328c0e72009-12-07 14:52:28 -08001292 public static EntityIterator newEntityIterator(Cursor cursor, ContentResolver resolver) {
1293 return new EntityIteratorImpl(cursor, resolver);
1294 }
1295
RoboErikc2d53302011-06-03 09:37:58 -07001296 /**
1297 * Creates a new iterator for events
1298 *
1299 * @param cursor An event query
1300 * @param provider For performing additional queries
1301 * @return an EntityIterator containing one entity per event in the
1302 * cursor
1303 */
Fred Quintana328c0e72009-12-07 14:52:28 -08001304 public static EntityIterator newEntityIterator(Cursor cursor,
1305 ContentProviderClient provider) {
1306 return new EntityIteratorImpl(cursor, provider);
1307 }
1308
1309 private static class EntityIteratorImpl extends CursorEntityIterator {
1310 private final ContentResolver mResolver;
1311 private final ContentProviderClient mProvider;
1312
1313 private static final String[] REMINDERS_PROJECTION = new String[] {
1314 Reminders.MINUTES,
1315 Reminders.METHOD,
1316 };
1317 private static final int COLUMN_MINUTES = 0;
1318 private static final int COLUMN_METHOD = 1;
1319
1320 private static final String[] ATTENDEES_PROJECTION = new String[] {
1321 Attendees.ATTENDEE_NAME,
1322 Attendees.ATTENDEE_EMAIL,
1323 Attendees.ATTENDEE_RELATIONSHIP,
1324 Attendees.ATTENDEE_TYPE,
1325 Attendees.ATTENDEE_STATUS,
Michael Chan48ec6222012-04-17 15:58:28 -07001326 Attendees.ATTENDEE_IDENTITY,
1327 Attendees.ATTENDEE_ID_NAMESPACE
Fred Quintana328c0e72009-12-07 14:52:28 -08001328 };
1329 private static final int COLUMN_ATTENDEE_NAME = 0;
1330 private static final int COLUMN_ATTENDEE_EMAIL = 1;
1331 private static final int COLUMN_ATTENDEE_RELATIONSHIP = 2;
1332 private static final int COLUMN_ATTENDEE_TYPE = 3;
1333 private static final int COLUMN_ATTENDEE_STATUS = 4;
Michael Chan48ec6222012-04-17 15:58:28 -07001334 private static final int COLUMN_ATTENDEE_IDENTITY = 5;
1335 private static final int COLUMN_ATTENDEE_ID_NAMESPACE = 6;
1336
Fred Quintana328c0e72009-12-07 14:52:28 -08001337 private static final String[] EXTENDED_PROJECTION = new String[] {
Marc Blank8f643c12010-04-29 14:16:48 -07001338 ExtendedProperties._ID,
Fred Quintana328c0e72009-12-07 14:52:28 -08001339 ExtendedProperties.NAME,
Marc Blank8f643c12010-04-29 14:16:48 -07001340 ExtendedProperties.VALUE
Fred Quintana328c0e72009-12-07 14:52:28 -08001341 };
Marc Blank8f643c12010-04-29 14:16:48 -07001342 private static final int COLUMN_ID = 0;
1343 private static final int COLUMN_NAME = 1;
1344 private static final int COLUMN_VALUE = 2;
Fred Quintana328c0e72009-12-07 14:52:28 -08001345
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001346 private static final String WHERE_EVENT_ID = "event_id=?";
1347
Fred Quintana328c0e72009-12-07 14:52:28 -08001348 public EntityIteratorImpl(Cursor cursor, ContentResolver resolver) {
1349 super(cursor);
1350 mResolver = resolver;
1351 mProvider = null;
1352 }
1353
1354 public EntityIteratorImpl(Cursor cursor, ContentProviderClient provider) {
1355 super(cursor);
1356 mResolver = null;
1357 mProvider = provider;
1358 }
1359
Marc Blank64a556d2010-02-25 12:53:16 -08001360 @Override
Fred Quintana328c0e72009-12-07 14:52:28 -08001361 public Entity getEntityAndIncrementCursor(Cursor cursor) throws RemoteException {
1362 // we expect the cursor is already at the row we need to read from
1363 final long eventId = cursor.getLong(cursor.getColumnIndexOrThrow(Events._ID));
1364 ContentValues cv = new ContentValues();
1365 cv.put(Events._ID, eventId);
1366 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, CALENDAR_ID);
Fred Quintana328c0e72009-12-07 14:52:28 -08001367 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, TITLE);
1368 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, DESCRIPTION);
1369 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, EVENT_LOCATION);
1370 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, STATUS);
1371 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, SELF_ATTENDEE_STATUS);
Fred Quintana328c0e72009-12-07 14:52:28 -08001372 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DTSTART);
1373 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DTEND);
1374 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, DURATION);
1375 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, EVENT_TIMEZONE);
RoboErikc0bd9bc2011-05-13 17:54:24 -07001376 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, EVENT_END_TIMEZONE);
Fred Quintana328c0e72009-12-07 14:52:28 -08001377 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ALL_DAY);
RoboErik651c02e2011-05-05 15:14:31 -07001378 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, ACCESS_LEVEL);
1379 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, AVAILABILITY);
Alon Albert971c28b2013-02-04 13:49:50 -08001380 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, EVENT_COLOR);
Alon Albert0a35dd52013-02-05 11:07:56 -08001381 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, EVENT_COLOR_KEY);
Fred Quintana328c0e72009-12-07 14:52:28 -08001382 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, HAS_ALARM);
1383 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv,
1384 HAS_EXTENDED_PROPERTIES);
1385 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, RRULE);
1386 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, RDATE);
1387 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, EXRULE);
1388 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, EXDATE);
RoboErik651c02e2011-05-05 15:14:31 -07001389 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ORIGINAL_SYNC_ID);
RoboErikc0bd9bc2011-05-13 17:54:24 -07001390 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ORIGINAL_ID);
Fred Quintana328c0e72009-12-07 14:52:28 -08001391 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv,
1392 ORIGINAL_INSTANCE_TIME);
1393 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, ORIGINAL_ALL_DAY);
1394 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, LAST_DATE);
1395 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, HAS_ATTENDEE_DATA);
1396 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv,
1397 GUESTS_CAN_INVITE_OTHERS);
1398 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, GUESTS_CAN_MODIFY);
1399 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, GUESTS_CAN_SEE_GUESTS);
Michael Chanbb9fd4a2012-04-24 17:32:03 -07001400 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_PACKAGE);
1401 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_URI);
Sara Ting4d6f90e2012-09-17 11:17:15 -07001402 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, UID_2445);
Fred Quintana328c0e72009-12-07 14:52:28 -08001403 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ORGANIZER);
Alon Albert0a9a2192012-09-18 11:10:49 -07001404 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, IS_ORGANIZER);
Fred Quintana328c0e72009-12-07 14:52:28 -08001405 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, _SYNC_ID);
RoboErik651c02e2011-05-05 15:14:31 -07001406 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DIRTY);
Alon Albert8ac6a632012-12-17 17:21:18 -08001407 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, MUTATORS);
Alon Albert866f40a2011-06-06 14:04:00 -07001408 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, LAST_SYNCED);
RoboErikc2d53302011-06-03 09:37:58 -07001409 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, DELETED);
RoboErik9734df52011-06-09 14:11:25 -07001410 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA1);
1411 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA2);
1412 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA3);
1413 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA4);
1414 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA5);
1415 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA6);
1416 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA7);
1417 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA8);
1418 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA9);
1419 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA10);
RoboErikbe010392011-05-26 12:28:38 -07001420 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC1);
1421 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC2);
1422 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC3);
1423 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC4);
1424 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC5);
1425 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC6);
RoboErik9734df52011-06-09 14:11:25 -07001426 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC7);
1427 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC8);
1428 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC9);
1429 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC10);
Fred Quintana328c0e72009-12-07 14:52:28 -08001430
1431 Entity entity = new Entity(cv);
1432 Cursor subCursor;
1433 if (mResolver != null) {
1434 subCursor = mResolver.query(Reminders.CONTENT_URI, REMINDERS_PROJECTION,
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001435 WHERE_EVENT_ID,
1436 new String[] { Long.toString(eventId) } /* selectionArgs */,
1437 null /* sortOrder */);
Fred Quintana328c0e72009-12-07 14:52:28 -08001438 } else {
1439 subCursor = mProvider.query(Reminders.CONTENT_URI, REMINDERS_PROJECTION,
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001440 WHERE_EVENT_ID,
1441 new String[] { Long.toString(eventId) } /* selectionArgs */,
1442 null /* sortOrder */);
Fred Quintana328c0e72009-12-07 14:52:28 -08001443 }
1444 try {
1445 while (subCursor.moveToNext()) {
1446 ContentValues reminderValues = new ContentValues();
1447 reminderValues.put(Reminders.MINUTES, subCursor.getInt(COLUMN_MINUTES));
1448 reminderValues.put(Reminders.METHOD, subCursor.getInt(COLUMN_METHOD));
1449 entity.addSubValue(Reminders.CONTENT_URI, reminderValues);
1450 }
1451 } finally {
1452 subCursor.close();
1453 }
1454
1455 if (mResolver != null) {
1456 subCursor = mResolver.query(Attendees.CONTENT_URI, ATTENDEES_PROJECTION,
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001457 WHERE_EVENT_ID,
1458 new String[] { Long.toString(eventId) } /* selectionArgs */,
1459 null /* sortOrder */);
Fred Quintana328c0e72009-12-07 14:52:28 -08001460 } else {
1461 subCursor = mProvider.query(Attendees.CONTENT_URI, ATTENDEES_PROJECTION,
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001462 WHERE_EVENT_ID,
1463 new String[] { Long.toString(eventId) } /* selectionArgs */,
1464 null /* sortOrder */);
Fred Quintana328c0e72009-12-07 14:52:28 -08001465 }
1466 try {
1467 while (subCursor.moveToNext()) {
1468 ContentValues attendeeValues = new ContentValues();
1469 attendeeValues.put(Attendees.ATTENDEE_NAME,
1470 subCursor.getString(COLUMN_ATTENDEE_NAME));
1471 attendeeValues.put(Attendees.ATTENDEE_EMAIL,
1472 subCursor.getString(COLUMN_ATTENDEE_EMAIL));
1473 attendeeValues.put(Attendees.ATTENDEE_RELATIONSHIP,
1474 subCursor.getInt(COLUMN_ATTENDEE_RELATIONSHIP));
1475 attendeeValues.put(Attendees.ATTENDEE_TYPE,
1476 subCursor.getInt(COLUMN_ATTENDEE_TYPE));
1477 attendeeValues.put(Attendees.ATTENDEE_STATUS,
1478 subCursor.getInt(COLUMN_ATTENDEE_STATUS));
Michael Chan48ec6222012-04-17 15:58:28 -07001479 attendeeValues.put(Attendees.ATTENDEE_IDENTITY,
Michael Chana07ea5d2012-07-13 14:10:40 -07001480 subCursor.getString(COLUMN_ATTENDEE_IDENTITY));
Michael Chan48ec6222012-04-17 15:58:28 -07001481 attendeeValues.put(Attendees.ATTENDEE_ID_NAMESPACE,
Michael Chana07ea5d2012-07-13 14:10:40 -07001482 subCursor.getString(COLUMN_ATTENDEE_ID_NAMESPACE));
Fred Quintana328c0e72009-12-07 14:52:28 -08001483 entity.addSubValue(Attendees.CONTENT_URI, attendeeValues);
1484 }
1485 } finally {
1486 subCursor.close();
1487 }
1488
1489 if (mResolver != null) {
1490 subCursor = mResolver.query(ExtendedProperties.CONTENT_URI, EXTENDED_PROJECTION,
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001491 WHERE_EVENT_ID,
1492 new String[] { Long.toString(eventId) } /* selectionArgs */,
1493 null /* sortOrder */);
Fred Quintana328c0e72009-12-07 14:52:28 -08001494 } else {
1495 subCursor = mProvider.query(ExtendedProperties.CONTENT_URI, EXTENDED_PROJECTION,
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001496 WHERE_EVENT_ID,
1497 new String[] { Long.toString(eventId) } /* selectionArgs */,
1498 null /* sortOrder */);
Fred Quintana328c0e72009-12-07 14:52:28 -08001499 }
1500 try {
1501 while (subCursor.moveToNext()) {
1502 ContentValues extendedValues = new ContentValues();
Marc Blank8f643c12010-04-29 14:16:48 -07001503 extendedValues.put(ExtendedProperties._ID,
1504 subCursor.getString(COLUMN_ID));
Ken Shirriff3b168922010-01-27 12:27:28 -08001505 extendedValues.put(ExtendedProperties.NAME,
1506 subCursor.getString(COLUMN_NAME));
Fred Quintana328c0e72009-12-07 14:52:28 -08001507 extendedValues.put(ExtendedProperties.VALUE,
Ken Shirriff3b168922010-01-27 12:27:28 -08001508 subCursor.getString(COLUMN_VALUE));
Fred Quintana328c0e72009-12-07 14:52:28 -08001509 entity.addSubValue(ExtendedProperties.CONTENT_URI, extendedValues);
1510 }
1511 } finally {
1512 subCursor.close();
1513 }
1514
1515 cursor.moveToNext();
1516 return entity;
1517 }
1518 }
1519 }
1520
1521 /**
RoboErikf4010c52011-06-17 11:04:26 -07001522 * Constants and helpers for the Events table, which contains details for
1523 * individual events. <h3>Operations</h3> All operations can be done either
1524 * as an app or as a sync adapter. To perform an operation as a sync adapter
1525 * {@link #CALLER_IS_SYNCADAPTER} should be set to true and
1526 * {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be set in the Uri
1527 * parameters. See
1528 * {@link Uri.Builder#appendQueryParameter(java.lang.String, java.lang.String)}
1529 * for details on adding parameters. Sync adapters have write access to more
1530 * columns but are restricted to a single account at a time.
RoboErikfe37b492011-06-16 12:31:56 -07001531 * <dl>
1532 * <dt><b>Insert</b></dt>
1533 * <dd>When inserting a new event the following fields must be included:
1534 * <ul>
1535 * <li>dtstart</li>
Michael Chane6fbf652011-10-18 14:43:11 -07001536 * <li>dtend if the event is non-recurring</li>
1537 * <li>duration if the event is recurring</li>
1538 * <li>rrule or rdate if the event is recurring</li>
RoboErik4172d952011-10-25 13:59:13 -07001539 * <li>eventTimezone</li>
RoboErikfe37b492011-06-16 12:31:56 -07001540 * <li>a calendar_id</li>
1541 * </ul>
1542 * There are also further requirements when inserting or updating an event.
1543 * See the section on Writing to Events.</dd>
1544 * <dt><b>Update</b></dt>
RoboErikf4010c52011-06-17 11:04:26 -07001545 * <dd>To perform an update of an Event the {@link Events#_ID} of the event
1546 * should be provided either as an appended id to the Uri (
RoboErikfe37b492011-06-16 12:31:56 -07001547 * {@link ContentUris#withAppendedId}) or as the first selection item--the
1548 * selection should start with "_id=?" and the first selectionArg should be
RoboErikf4010c52011-06-17 11:04:26 -07001549 * the _id of the event. Updates may also be done using a selection and no
1550 * id. Updating an event must respect the same rules as inserting and is
1551 * further restricted in the fields that can be written. See the section on
1552 * Writing to Events.</dd>
RoboErikfe37b492011-06-16 12:31:56 -07001553 * <dt><b>Delete</b></dt>
1554 * <dd>Events can be deleted either by the {@link Events#_ID} as an appended
1555 * id on the Uri or using any standard selection. If an appended id is used
1556 * a selection is not allowed. There are two versions of delete: as an app
1557 * and as a sync adapter. An app delete will set the deleted column on an
1558 * event and remove all instances of that event. A sync adapter delete will
1559 * remove the event from the database and all associated data.</dd>
1560 * <dt><b>Query</b></dt>
1561 * <dd>Querying the Events table will get you all information about a set of
1562 * events except their reminders, attendees, and extended properties. There
1563 * will be one row returned for each event that matches the query selection,
1564 * or at most a single row if the {@link Events#_ID} is appended to the Uri.
1565 * Recurring events will only return a single row regardless of the number
1566 * of times that event repeats.</dd>
1567 * </dl>
1568 * <h3>Writing to Events</h3> There are further restrictions on all Updates
1569 * and Inserts in the Events table:
1570 * <ul>
1571 * <li>If allDay is set to 1 eventTimezone must be {@link Time#TIMEZONE_UTC}
1572 * and the time must correspond to a midnight boundary.</li>
1573 * <li>Exceptions are not allowed to recur. If rrule or rdate is not empty,
1574 * original_id and original_sync_id must be empty.</li>
1575 * <li>In general a calendar_id should not be modified after insertion. This
1576 * is not explicitly forbidden but many sync adapters will not behave in an
1577 * expected way if the calendar_id is modified.</li>
1578 * </ul>
1579 * The following Events columns are writable by both an app and a sync
1580 * adapter.
1581 * <ul>
1582 * <li>{@link #CALENDAR_ID}</li>
1583 * <li>{@link #ORGANIZER}</li>
1584 * <li>{@link #TITLE}</li>
1585 * <li>{@link #EVENT_LOCATION}</li>
1586 * <li>{@link #DESCRIPTION}</li>
1587 * <li>{@link #EVENT_COLOR}</li>
1588 * <li>{@link #DTSTART}</li>
1589 * <li>{@link #DTEND}</li>
1590 * <li>{@link #EVENT_TIMEZONE}</li>
1591 * <li>{@link #EVENT_END_TIMEZONE}</li>
1592 * <li>{@link #DURATION}</li>
1593 * <li>{@link #ALL_DAY}</li>
1594 * <li>{@link #RRULE}</li>
1595 * <li>{@link #RDATE}</li>
1596 * <li>{@link #EXRULE}</li>
1597 * <li>{@link #EXDATE}</li>
1598 * <li>{@link #ORIGINAL_ID}</li>
1599 * <li>{@link #ORIGINAL_SYNC_ID}</li>
1600 * <li>{@link #ORIGINAL_INSTANCE_TIME}</li>
1601 * <li>{@link #ORIGINAL_ALL_DAY}</li>
1602 * <li>{@link #ACCESS_LEVEL}</li>
1603 * <li>{@link #AVAILABILITY}</li>
1604 * <li>{@link #GUESTS_CAN_MODIFY}</li>
1605 * <li>{@link #GUESTS_CAN_INVITE_OTHERS}</li>
1606 * <li>{@link #GUESTS_CAN_SEE_GUESTS}</li>
Michael Chanbb9fd4a2012-04-24 17:32:03 -07001607 * <li>{@link #CUSTOM_APP_PACKAGE}</li>
1608 * <li>{@link #CUSTOM_APP_URI}</li>
Sara Ting4d6f90e2012-09-17 11:17:15 -07001609 * <li>{@link #UID_2445}</li>
RoboErikfe37b492011-06-16 12:31:56 -07001610 * </ul>
1611 * The following Events columns are writable only by a sync adapter
1612 * <ul>
1613 * <li>{@link #DIRTY}</li>
Alon Albert8ac6a632012-12-17 17:21:18 -08001614 * <li>{@link #MUTATORS}</li>
RoboErikfe37b492011-06-16 12:31:56 -07001615 * <li>{@link #_SYNC_ID}</li>
1616 * <li>{@link #SYNC_DATA1}</li>
1617 * <li>{@link #SYNC_DATA2}</li>
1618 * <li>{@link #SYNC_DATA3}</li>
1619 * <li>{@link #SYNC_DATA4}</li>
1620 * <li>{@link #SYNC_DATA5}</li>
1621 * <li>{@link #SYNC_DATA6}</li>
1622 * <li>{@link #SYNC_DATA7}</li>
1623 * <li>{@link #SYNC_DATA8}</li>
1624 * <li>{@link #SYNC_DATA9}</li>
1625 * <li>{@link #SYNC_DATA10}</li>
1626 * </ul>
1627 * The remaining columns are either updated by the provider only or are
1628 * views into other tables and cannot be changed through the Events table.
Fred Quintana328c0e72009-12-07 14:52:28 -08001629 */
RoboErik9734df52011-06-09 14:11:25 -07001630 public static final class Events implements BaseColumns, SyncColumns, EventsColumns,
RoboErike00d5892011-06-23 15:16:55 -07001631 CalendarColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632
RoboErikc2d53302011-06-03 09:37:58 -07001633 /**
RoboErikc2d53302011-06-03 09:37:58 -07001634 * The content:// style URL for interacting with events. Appending an
1635 * event id using {@link ContentUris#withAppendedId(Uri, long)} will
1636 * specify a single event.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 */
RoboErikc2d53302011-06-03 09:37:58 -07001638 @SuppressWarnings("hiding")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 public static final Uri CONTENT_URI =
Ken Shirriffa69a23b2010-01-21 17:32:39 -08001640 Uri.parse("content://" + AUTHORITY + "/events");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 /**
Andy McFadden4a8c4782011-05-24 13:00:29 -07001643 * The content:// style URI for recurring event exceptions. Insertions require an
1644 * appended event ID. Deletion of exceptions requires both the original event ID and
1645 * the exception event ID (see {@link Uri.Builder#appendPath}).
1646 */
RoboErik083cd2d2011-06-30 11:53:05 -07001647 public static final Uri CONTENT_EXCEPTION_URI =
Andy McFadden4a8c4782011-05-24 13:00:29 -07001648 Uri.parse("content://" + AUTHORITY + "/exception");
1649
1650 /**
RoboErik36726962011-06-14 14:01:15 -07001651 * This utility class cannot be instantiated
1652 */
1653 private Events() {}
1654
1655 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 * The default sort order for this table
1657 */
RoboErikc2d53302011-06-03 09:37:58 -07001658 private static final String DEFAULT_SORT_ORDER = "";
RoboErik651c02e2011-05-05 15:14:31 -07001659
1660 /**
1661 * These are columns that should only ever be updated by the provider,
1662 * either because they are views mapped to another table or because they
RoboErik083cd2d2011-06-30 11:53:05 -07001663 * are used for provider only functionality. TODO move to provider
1664 *
1665 * @hide
RoboErik651c02e2011-05-05 15:14:31 -07001666 */
1667 public static String[] PROVIDER_WRITABLE_COLUMNS = new String[] {
1668 ACCOUNT_NAME,
RoboErikc2d53302011-06-03 09:37:58 -07001669 ACCOUNT_TYPE,
1670 CAL_SYNC1,
1671 CAL_SYNC2,
1672 CAL_SYNC3,
1673 CAL_SYNC4,
1674 CAL_SYNC5,
Alon Albert866f40a2011-06-06 14:04:00 -07001675 CAL_SYNC6,
RoboErik9734df52011-06-09 14:11:25 -07001676 CAL_SYNC7,
1677 CAL_SYNC8,
1678 CAL_SYNC9,
1679 CAL_SYNC10,
1680 ALLOWED_REMINDERS,
RoboErikc7ef9392011-10-27 14:11:44 -07001681 ALLOWED_ATTENDEE_TYPES,
1682 ALLOWED_AVAILABILITY,
RoboErik9734df52011-06-09 14:11:25 -07001683 CALENDAR_ACCESS_LEVEL,
1684 CALENDAR_COLOR,
1685 CALENDAR_TIME_ZONE,
1686 CAN_MODIFY_TIME_ZONE,
1687 CAN_ORGANIZER_RESPOND,
1688 CALENDAR_DISPLAY_NAME,
Alon Albert866f40a2011-06-06 14:04:00 -07001689 CAN_PARTIALLY_UPDATE,
RoboErik9734df52011-06-09 14:11:25 -07001690 SYNC_EVENTS,
1691 VISIBLE,
RoboErik651c02e2011-05-05 15:14:31 -07001692 };
1693
1694 /**
1695 * These fields are only writable by a sync adapter. To modify them the
1696 * caller must include CALLER_IS_SYNCADAPTER, _SYNC_ACCOUNT, and
RoboErik083cd2d2011-06-30 11:53:05 -07001697 * _SYNC_ACCOUNT_TYPE in the query parameters. TODO move to provider.
1698 *
1699 * @hide
RoboErik651c02e2011-05-05 15:14:31 -07001700 */
1701 public static final String[] SYNC_WRITABLE_COLUMNS = new String[] {
1702 _SYNC_ID,
RoboErik651c02e2011-05-05 15:14:31 -07001703 DIRTY,
Alon Albert8ac6a632012-12-17 17:21:18 -08001704 MUTATORS,
RoboErik9734df52011-06-09 14:11:25 -07001705 SYNC_DATA1,
1706 SYNC_DATA2,
1707 SYNC_DATA3,
1708 SYNC_DATA4,
1709 SYNC_DATA5,
1710 SYNC_DATA6,
1711 SYNC_DATA7,
1712 SYNC_DATA8,
1713 SYNC_DATA9,
1714 SYNC_DATA10,
RoboErik651c02e2011-05-05 15:14:31 -07001715 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 }
1717
1718 /**
RoboErikc2d53302011-06-03 09:37:58 -07001719 * Fields and helpers for interacting with Instances. An instance is a
1720 * single occurrence of an event including time zone specific start and end
RoboErik3771fcb2011-06-16 15:41:31 -07001721 * days and minutes. The instances table is not writable and only provides a
1722 * way to query event occurrences.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 */
RoboErike00d5892011-06-23 15:16:55 -07001724 public static final class Instances implements BaseColumns, EventsColumns, CalendarColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725
RoboErike00d5892011-06-23 15:16:55 -07001726 private static final String WHERE_CALENDARS_SELECTED = Calendars.VISIBLE + "=?";
1727 private static final String[] WHERE_CALENDARS_ARGS = {
1728 "1"
1729 };
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001730
RoboErikc2d53302011-06-03 09:37:58 -07001731 /**
RoboErik36726962011-06-14 14:01:15 -07001732 * This utility class cannot be instantiated
1733 */
1734 private Instances() {}
1735
1736 /**
RoboErikc2d53302011-06-03 09:37:58 -07001737 * Performs a query to return all visible instances in the given range.
1738 * This is a blocking function and should not be done on the UI thread.
1739 * This will cause an expansion of recurring events to fill this time
1740 * range if they are not already expanded and will slow down for larger
1741 * time ranges with many recurring events.
1742 *
1743 * @param cr The ContentResolver to use for the query
1744 * @param projection The columns to return
1745 * @param begin The start of the time range to query in UTC millis since
1746 * epoch
1747 * @param end The end of the time range to query in UTC millis since
1748 * epoch
1749 * @return A Cursor containing all instances in the given range
1750 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 public static final Cursor query(ContentResolver cr, String[] projection,
1752 long begin, long end) {
1753 Uri.Builder builder = CONTENT_URI.buildUpon();
1754 ContentUris.appendId(builder, begin);
1755 ContentUris.appendId(builder, end);
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08001756 return cr.query(builder.build(), projection, WHERE_CALENDARS_SELECTED,
RoboErike00d5892011-06-23 15:16:55 -07001757 WHERE_CALENDARS_ARGS, DEFAULT_SORT_ORDER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758 }
1759
RoboErikc2d53302011-06-03 09:37:58 -07001760 /**
1761 * Performs a query to return all visible instances in the given range
1762 * that match the given query. This is a blocking function and should
1763 * not be done on the UI thread. This will cause an expansion of
1764 * recurring events to fill this time range if they are not already
1765 * expanded and will slow down for larger time ranges with many
1766 * recurring events.
1767 *
1768 * @param cr The ContentResolver to use for the query
1769 * @param projection The columns to return
1770 * @param begin The start of the time range to query in UTC millis since
1771 * epoch
1772 * @param end The end of the time range to query in UTC millis since
1773 * epoch
1774 * @param searchQuery A string of space separated search terms. Segments
1775 * enclosed by double quotes will be treated as a single
1776 * term.
1777 * @return A Cursor of instances matching the search terms in the given
1778 * time range
1779 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 public static final Cursor query(ContentResolver cr, String[] projection,
Mason Tang19f84582010-07-08 18:01:41 -07001781 long begin, long end, String searchQuery) {
1782 Uri.Builder builder = CONTENT_SEARCH_URI.buildUpon();
1783 ContentUris.appendId(builder, begin);
1784 ContentUris.appendId(builder, end);
RoboErikc2d53302011-06-03 09:37:58 -07001785 builder = builder.appendPath(searchQuery);
RoboErike00d5892011-06-23 15:16:55 -07001786 return cr.query(builder.build(), projection, WHERE_CALENDARS_SELECTED,
1787 WHERE_CALENDARS_ARGS, DEFAULT_SORT_ORDER);
RoboErikc2d53302011-06-03 09:37:58 -07001788 }
1789
1790 /**
1791 * The content:// style URL for querying an instance range. The begin
1792 * and end of the range to query should be added as path segments if
1793 * this is used directly.
1794 */
1795 @SuppressWarnings("hiding")
Ken Shirriffa69a23b2010-01-21 17:32:39 -08001796 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY +
1797 "/instances/when");
RoboErikc2d53302011-06-03 09:37:58 -07001798 /**
1799 * The content:// style URL for querying an instance range by Julian
1800 * Day. The start and end day should be added as path segments if this
1801 * is used directly.
1802 */
Michael Chan2cfb0d12009-06-30 18:11:23 -07001803 public static final Uri CONTENT_BY_DAY_URI =
Ken Shirriffa69a23b2010-01-21 17:32:39 -08001804 Uri.parse("content://" + AUTHORITY + "/instances/whenbyday");
RoboErikc2d53302011-06-03 09:37:58 -07001805 /**
1806 * The content:// style URL for querying an instance range with a search
1807 * term. The begin, end, and search string should be appended as path
1808 * segments if this is used directly.
1809 */
Mason Tang19f84582010-07-08 18:01:41 -07001810 public static final Uri CONTENT_SEARCH_URI = Uri.parse("content://" + AUTHORITY +
1811 "/instances/search");
RoboErikc2d53302011-06-03 09:37:58 -07001812 /**
1813 * The content:// style URL for querying an instance range with a search
1814 * term. The start day, end day, and search string should be appended as
1815 * path segments if this is used directly.
1816 */
Mason Tang19f84582010-07-08 18:01:41 -07001817 public static final Uri CONTENT_SEARCH_BY_DAY_URI =
1818 Uri.parse("content://" + AUTHORITY + "/instances/searchbyday");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819
1820 /**
1821 * The default sort order for this table.
1822 */
RoboErikc2d53302011-06-03 09:37:58 -07001823 private static final String DEFAULT_SORT_ORDER = "begin ASC";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001824
1825 /**
RoboErikc2d53302011-06-03 09:37:58 -07001826 * The beginning time of the instance, in UTC milliseconds. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 * <P>Type: INTEGER (long; millis since epoch)</P>
1828 */
1829 public static final String BEGIN = "begin";
1830
1831 /**
RoboErikc2d53302011-06-03 09:37:58 -07001832 * The ending time of the instance, in UTC milliseconds. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 * <P>Type: INTEGER (long; millis since epoch)</P>
1834 */
1835 public static final String END = "end";
1836
1837 /**
RoboErikc2d53302011-06-03 09:37:58 -07001838 * The _id of the event for this instance. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 * <P>Type: INTEGER (long, foreign key to the Events table)</P>
1840 */
1841 public static final String EVENT_ID = "event_id";
1842
1843 /**
RoboErikc2d53302011-06-03 09:37:58 -07001844 * The Julian start day of the instance, relative to the local time
1845 * zone. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 * <P>Type: INTEGER (int)</P>
1847 */
1848 public static final String START_DAY = "startDay";
1849
1850 /**
RoboErikc2d53302011-06-03 09:37:58 -07001851 * The Julian end day of the instance, relative to the local time
1852 * zone. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 * <P>Type: INTEGER (int)</P>
1854 */
1855 public static final String END_DAY = "endDay";
1856
1857 /**
1858 * The start minute of the instance measured from midnight in the
RoboErikc2d53302011-06-03 09:37:58 -07001859 * local time zone. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001860 * <P>Type: INTEGER (int)</P>
1861 */
1862 public static final String START_MINUTE = "startMinute";
1863
1864 /**
1865 * The end minute of the instance measured from midnight in the
RoboErikc2d53302011-06-03 09:37:58 -07001866 * local time zone. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 * <P>Type: INTEGER (int)</P>
1868 */
1869 public static final String END_MINUTE = "endMinute";
1870 }
1871
RoboErikb2c75602011-06-13 12:53:48 -07001872 protected interface CalendarCacheColumns {
Erik71ad58c2010-09-13 16:41:35 -07001873 /**
RoboErikc2d53302011-06-03 09:37:58 -07001874 * The key for the setting. Keys are defined in {@link CalendarCache}.
Erik71ad58c2010-09-13 16:41:35 -07001875 */
1876 public static final String KEY = "key";
1877
1878 /**
1879 * The value of the given setting.
1880 */
1881 public static final String VALUE = "value";
1882 }
1883
RoboErik083cd2d2011-06-30 11:53:05 -07001884 /**
1885 * CalendarCache stores some settings for calendar including the current
1886 * time zone for the instances. These settings are stored using a key/value
1887 * scheme. A {@link #KEY} must be specified when updating these values.
1888 */
RoboErik36726962011-06-14 14:01:15 -07001889 public static final class CalendarCache implements CalendarCacheColumns {
Erik71ad58c2010-09-13 16:41:35 -07001890 /**
1891 * The URI to use for retrieving the properties from the Calendar db.
1892 */
1893 public static final Uri URI =
1894 Uri.parse("content://" + AUTHORITY + "/properties");
Erik71ad58c2010-09-13 16:41:35 -07001895
1896 /**
RoboErik36726962011-06-14 14:01:15 -07001897 * This utility class cannot be instantiated
1898 */
1899 private CalendarCache() {}
1900
1901 /**
Erik71ad58c2010-09-13 16:41:35 -07001902 * They key for updating the use of auto/home time zones in Calendar.
1903 * Valid values are {@link #TIMEZONE_TYPE_AUTO} or
1904 * {@link #TIMEZONE_TYPE_HOME}.
1905 */
RoboErik083cd2d2011-06-30 11:53:05 -07001906 public static final String KEY_TIMEZONE_TYPE = "timezoneType";
Erik71ad58c2010-09-13 16:41:35 -07001907
1908 /**
1909 * The key for updating the time zone used by the provider when it
1910 * generates the instances table. This should only be written if the
1911 * type is set to {@link #TIMEZONE_TYPE_HOME}. A valid time zone id
1912 * should be written to this field.
1913 */
RoboErik083cd2d2011-06-30 11:53:05 -07001914 public static final String KEY_TIMEZONE_INSTANCES = "timezoneInstances";
Erik71ad58c2010-09-13 16:41:35 -07001915
1916 /**
1917 * The key for reading the last time zone set by the user. This should
1918 * only be read by apps and it will be automatically updated whenever
RoboErik083cd2d2011-06-30 11:53:05 -07001919 * {@link #KEY_TIMEZONE_INSTANCES} is updated with
Erik71ad58c2010-09-13 16:41:35 -07001920 * {@link #TIMEZONE_TYPE_HOME} set.
1921 */
RoboErik083cd2d2011-06-30 11:53:05 -07001922 public static final String KEY_TIMEZONE_INSTANCES_PREVIOUS = "timezoneInstancesPrevious";
Erik71ad58c2010-09-13 16:41:35 -07001923
1924 /**
RoboErik083cd2d2011-06-30 11:53:05 -07001925 * The value to write to {@link #KEY_TIMEZONE_TYPE} if the provider
Erik71ad58c2010-09-13 16:41:35 -07001926 * should stay in sync with the device's time zone.
1927 */
1928 public static final String TIMEZONE_TYPE_AUTO = "auto";
1929
1930 /**
RoboErik083cd2d2011-06-30 11:53:05 -07001931 * The value to write to {@link #KEY_TIMEZONE_TYPE} if the provider
Erik71ad58c2010-09-13 16:41:35 -07001932 * should use a fixed time zone set by the user.
1933 */
1934 public static final String TIMEZONE_TYPE_HOME = "home";
1935 }
1936
1937 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001938 * A few Calendar globals are needed in the CalendarProvider for expanding
RoboErik59dab492011-06-17 11:09:36 -07001939 * the Instances table and these are all stored in the first (and only) row
1940 * of the CalendarMetaData table.
1941 *
1942 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001943 */
RoboErikb2c75602011-06-13 12:53:48 -07001944 protected interface CalendarMetaDataColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001945 /**
1946 * The local timezone that was used for precomputing the fields
1947 * in the Instances table.
1948 */
1949 public static final String LOCAL_TIMEZONE = "localTimezone";
1950
1951 /**
1952 * The minimum time used in expanding the Instances table,
1953 * in UTC milliseconds.
1954 * <P>Type: INTEGER</P>
1955 */
1956 public static final String MIN_INSTANCE = "minInstance";
1957
1958 /**
1959 * The maximum time used in expanding the Instances table,
1960 * in UTC milliseconds.
1961 * <P>Type: INTEGER</P>
1962 */
1963 public static final String MAX_INSTANCE = "maxInstance";
1964
1965 /**
Erik37634642009-12-23 15:24:14 -08001966 * The minimum Julian day in the EventDays table.
1967 * <P>Type: INTEGER</P>
1968 */
1969 public static final String MIN_EVENTDAYS = "minEventDays";
1970
1971 /**
1972 * The maximum Julian day in the EventDays table.
1973 * <P>Type: INTEGER</P>
1974 */
1975 public static final String MAX_EVENTDAYS = "maxEventDays";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001976 }
Ken Shirriff5b387e12009-10-23 09:50:41 -07001977
RoboErikc2d53302011-06-03 09:37:58 -07001978 /**
1979 * @hide
1980 */
Fabrice Di Meglio50563552010-06-15 16:35:20 -07001981 public static final class CalendarMetaData implements CalendarMetaDataColumns, BaseColumns {
RoboErik36726962011-06-14 14:01:15 -07001982
1983 /**
1984 * This utility class cannot be instantiated
1985 */
1986 private CalendarMetaData() {}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 }
Erik37634642009-12-23 15:24:14 -08001988
RoboErikb2c75602011-06-13 12:53:48 -07001989 protected interface EventDaysColumns {
Erik37634642009-12-23 15:24:14 -08001990 /**
RoboErikc2d53302011-06-03 09:37:58 -07001991 * The Julian starting day number. Column name.
Erik37634642009-12-23 15:24:14 -08001992 * <P>Type: INTEGER (int)</P>
1993 */
1994 public static final String STARTDAY = "startDay";
RoboErikc2d53302011-06-03 09:37:58 -07001995 /**
1996 * The Julian ending day number. Column name.
1997 * <P>Type: INTEGER (int)</P>
1998 */
Erikbd8e2e22010-01-07 11:56:46 -08001999 public static final String ENDDAY = "endDay";
Erik37634642009-12-23 15:24:14 -08002000
2001 }
2002
RoboErikc2d53302011-06-03 09:37:58 -07002003 /**
2004 * Fields and helpers for querying for a list of days that contain events.
2005 */
Erik37634642009-12-23 15:24:14 -08002006 public static final class EventDays implements EventDaysColumns {
RoboErikb2c75602011-06-13 12:53:48 -07002007 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
RoboErikc2d53302011-06-03 09:37:58 -07002008 + "/instances/groupbyday");
RoboErikc2d53302011-06-03 09:37:58 -07002009 private static final String SELECTION = "selected=1";
2010
2011 /**
RoboErik36726962011-06-14 14:01:15 -07002012 * This utility class cannot be instantiated
2013 */
2014 private EventDays() {}
2015
2016 /**
RoboErikc2d53302011-06-03 09:37:58 -07002017 * Retrieves the days with events for the Julian days starting at
2018 * "startDay" for "numDays". It returns a cursor containing startday and
2019 * endday representing the max range of days for all events beginning on
2020 * each startday.This is a blocking function and should not be done on
2021 * the UI thread.
RoboErik36726962011-06-14 14:01:15 -07002022 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002023 * @param cr the ContentResolver
2024 * @param startDay the first Julian day in the range
2025 * @param numDays the number of days to load (must be at least 1)
RoboErik58644022011-07-08 13:39:05 -07002026 * @param projection the columns to return in the cursor
RoboErikc2d53302011-06-03 09:37:58 -07002027 * @return a database cursor containing a list of start and end days for
2028 * events
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002029 */
RoboErik58644022011-07-08 13:39:05 -07002030 public static final Cursor query(ContentResolver cr, int startDay, int numDays,
2031 String[] projection) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002032 if (numDays < 1) {
2033 return null;
2034 }
2035 int endDay = startDay + numDays - 1;
2036 Uri.Builder builder = CONTENT_URI.buildUpon();
2037 ContentUris.appendId(builder, startDay);
2038 ContentUris.appendId(builder, endDay);
RoboErik58644022011-07-08 13:39:05 -07002039 return cr.query(builder.build(), projection, SELECTION,
Erik37634642009-12-23 15:24:14 -08002040 null /* selection args */, STARTDAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002041 }
2042 }
2043
RoboErikb2c75602011-06-13 12:53:48 -07002044 protected interface RemindersColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002045 /**
RoboErikc2d53302011-06-03 09:37:58 -07002046 * The event the reminder belongs to. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 * <P>Type: INTEGER (foreign key to the Events table)</P>
2048 */
2049 public static final String EVENT_ID = "event_id";
2050
2051 /**
2052 * The minutes prior to the event that the alarm should ring. -1
2053 * specifies that we should use the default value for the system.
RoboErikc2d53302011-06-03 09:37:58 -07002054 * Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002055 * <P>Type: INTEGER</P>
2056 */
2057 public static final String MINUTES = "minutes";
2058
RoboErikc2d53302011-06-03 09:37:58 -07002059 /**
2060 * Passing this as a minutes value will use the default reminder
2061 * minutes.
2062 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002063 public static final int MINUTES_DEFAULT = -1;
2064
2065 /**
RoboErikc2d53302011-06-03 09:37:58 -07002066 * The alarm method, as set on the server. {@link #METHOD_DEFAULT},
Alon Albertbd251612012-02-23 10:30:51 -08002067 * {@link #METHOD_ALERT}, {@link #METHOD_EMAIL}, {@link #METHOD_SMS} and
2068 * {@link #METHOD_ALARM} are possible values; the device will only
2069 * process {@link #METHOD_DEFAULT} and {@link #METHOD_ALERT} reminders
2070 * (the other types are simply stored so we can send the same reminder
2071 * info back to the server when we make changes).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 */
2073 public static final String METHOD = "method";
2074
2075 public static final int METHOD_DEFAULT = 0;
2076 public static final int METHOD_ALERT = 1;
2077 public static final int METHOD_EMAIL = 2;
2078 public static final int METHOD_SMS = 3;
Alon Albertbd251612012-02-23 10:30:51 -08002079 public static final int METHOD_ALARM = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002080 }
2081
RoboErikc2d53302011-06-03 09:37:58 -07002082 /**
RoboErik3771fcb2011-06-16 15:41:31 -07002083 * Fields and helpers for accessing reminders for an event. Each row of this
2084 * table represents a single reminder for an event. Calling
RoboErik58644022011-07-08 13:39:05 -07002085 * {@link #query(ContentResolver, long, String[])} will return a list of reminders for
RoboErik3771fcb2011-06-16 15:41:31 -07002086 * the event with the given eventId. Both apps and sync adapters may write
2087 * to this table. There are three writable fields and all of them must be
2088 * included when inserting a new reminder. They are:
2089 * <ul>
2090 * <li>{@link #EVENT_ID}</li>
2091 * <li>{@link #MINUTES}</li>
2092 * <li>{@link #METHOD}</li>
2093 * </ul>
RoboErikc2d53302011-06-03 09:37:58 -07002094 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002095 public static final class Reminders implements BaseColumns, RemindersColumns, EventsColumns {
RoboErikbec6c362011-06-14 11:06:01 -07002096 private static final String REMINDERS_WHERE = CalendarContract.Reminders.EVENT_ID + "=?";
RoboErikc2d53302011-06-03 09:37:58 -07002097 @SuppressWarnings("hiding")
Ken Shirriffa69a23b2010-01-21 17:32:39 -08002098 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/reminders");
RoboErikc2d53302011-06-03 09:37:58 -07002099
2100 /**
RoboErik36726962011-06-14 14:01:15 -07002101 * This utility class cannot be instantiated
2102 */
2103 private Reminders() {}
2104
2105 /**
RoboErikc2d53302011-06-03 09:37:58 -07002106 * Queries all reminders associated with the given event. This is a
2107 * blocking call and should not be done on the UI thread.
RoboErik36726962011-06-14 14:01:15 -07002108 *
RoboErikc2d53302011-06-03 09:37:58 -07002109 * @param cr The content resolver to use for the query
2110 * @param eventId The id of the event to retrieve reminders for
RoboErik58644022011-07-08 13:39:05 -07002111 * @param projection the columns to return in the cursor
RoboErikc2d53302011-06-03 09:37:58 -07002112 * @return A Cursor containing all reminders for the event
2113 */
RoboErik58644022011-07-08 13:39:05 -07002114 public static final Cursor query(ContentResolver cr, long eventId, String[] projection) {
RoboErikc2d53302011-06-03 09:37:58 -07002115 String[] remArgs = {Long.toString(eventId)};
RoboErik58644022011-07-08 13:39:05 -07002116 return cr.query(CONTENT_URI, projection, REMINDERS_WHERE, remArgs /*selection args*/,
RoboErikc2d53302011-06-03 09:37:58 -07002117 null /* sort order */);
2118 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002119 }
2120
RoboErikb2c75602011-06-13 12:53:48 -07002121 protected interface CalendarAlertsColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 /**
RoboErikc2d53302011-06-03 09:37:58 -07002123 * The event that the alert belongs to. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124 * <P>Type: INTEGER (foreign key to the Events table)</P>
2125 */
2126 public static final String EVENT_ID = "event_id";
2127
2128 /**
RoboErikc2d53302011-06-03 09:37:58 -07002129 * The start time of the event, in UTC. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002130 * <P>Type: INTEGER (long; millis since epoch)</P>
2131 */
2132 public static final String BEGIN = "begin";
2133
2134 /**
RoboErikc2d53302011-06-03 09:37:58 -07002135 * The end time of the event, in UTC. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136 * <P>Type: INTEGER (long; millis since epoch)</P>
2137 */
2138 public static final String END = "end";
2139
2140 /**
RoboErikc2d53302011-06-03 09:37:58 -07002141 * The alarm time of the event, in UTC. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 * <P>Type: INTEGER (long; millis since epoch)</P>
2143 */
2144 public static final String ALARM_TIME = "alarmTime";
2145
2146 /**
2147 * The creation time of this database entry, in UTC.
RoboErikc2d53302011-06-03 09:37:58 -07002148 * Useful for debugging missed reminders. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 * <P>Type: INTEGER (long; millis since epoch)</P>
2150 */
2151 public static final String CREATION_TIME = "creationTime";
2152
2153 /**
2154 * The time that the alarm broadcast was received by the Calendar app,
RoboErikc2d53302011-06-03 09:37:58 -07002155 * in UTC. Useful for debugging missed reminders. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 * <P>Type: INTEGER (long; millis since epoch)</P>
2157 */
2158 public static final String RECEIVED_TIME = "receivedTime";
2159
2160 /**
2161 * The time that the notification was created by the Calendar app,
RoboErikc2d53302011-06-03 09:37:58 -07002162 * in UTC. Useful for debugging missed reminders. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163 * <P>Type: INTEGER (long; millis since epoch)</P>
2164 */
2165 public static final String NOTIFY_TIME = "notifyTime";
2166
2167 /**
RoboErik083cd2d2011-06-30 11:53:05 -07002168 * The state of this alert. It starts out as {@link #STATE_SCHEDULED}, then
2169 * when the alarm goes off, it changes to {@link #STATE_FIRED}, and then when
2170 * the user dismisses the alarm it changes to {@link #STATE_DISMISSED}. Column
RoboErikc2d53302011-06-03 09:37:58 -07002171 * name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 * <P>Type: INTEGER</P>
2173 */
2174 public static final String STATE = "state";
2175
RoboErik083cd2d2011-06-30 11:53:05 -07002176 /**
2177 * An alert begins in this state when it is first created.
2178 */
2179 public static final int STATE_SCHEDULED = 0;
2180 /**
2181 * After a notification for an alert has been created it should be
2182 * updated to fired.
2183 */
2184 public static final int STATE_FIRED = 1;
2185 /**
2186 * Once the user has dismissed the notification the alert's state should
2187 * be set to dismissed so it is not fired again.
2188 */
2189 public static final int STATE_DISMISSED = 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190
2191 /**
RoboErikc2d53302011-06-03 09:37:58 -07002192 * The number of minutes that this alarm precedes the start time. Column
2193 * name.
2194 * <P>Type: INTEGER</P>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002195 */
2196 public static final String MINUTES = "minutes";
2197
2198 /**
RoboErikc2d53302011-06-03 09:37:58 -07002199 * The default sort order for this alerts queries
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002200 */
Michael Chancdaeafd2009-10-29 00:11:58 -07002201 public static final String DEFAULT_SORT_ORDER = "begin ASC,title ASC";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002202 }
2203
RoboErikc2d53302011-06-03 09:37:58 -07002204 /**
2205 * Fields and helpers for accessing calendar alerts information. These
RoboErik3771fcb2011-06-16 15:41:31 -07002206 * fields are for tracking which alerts have been fired. Scheduled alarms
RoboErike00d5892011-06-23 15:16:55 -07002207 * will generate an intent using {@link #ACTION_EVENT_REMINDER}. Apps that
RoboErik3771fcb2011-06-16 15:41:31 -07002208 * receive this action may update the {@link #STATE} for the reminder when
2209 * they have finished handling it. Apps that have their notifications
2210 * disabled should not modify the table to ensure that they do not conflict
2211 * with another app that is generating a notification. In general, apps
2212 * should not need to write to this table directly except to update the
2213 * state of a reminder.
RoboErikc2d53302011-06-03 09:37:58 -07002214 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 public static final class CalendarAlerts implements BaseColumns,
RoboErike00d5892011-06-23 15:16:55 -07002216 CalendarAlertsColumns, EventsColumns, CalendarColumns {
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08002217
RoboErikc2d53302011-06-03 09:37:58 -07002218 /**
2219 * @hide
2220 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 public static final String TABLE_NAME = "CalendarAlerts";
RoboErikc2d53302011-06-03 09:37:58 -07002222 /**
2223 * The Uri for querying calendar alert information
2224 */
2225 @SuppressWarnings("hiding")
Ken Shirriffa69a23b2010-01-21 17:32:39 -08002226 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY +
2227 "/calendar_alerts");
Ken Shirriff5b387e12009-10-23 09:50:41 -07002228
RoboErik36726962011-06-14 14:01:15 -07002229 /**
2230 * This utility class cannot be instantiated
2231 */
2232 private CalendarAlerts() {}
2233
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08002234 private static final String WHERE_ALARM_EXISTS = EVENT_ID + "=?"
2235 + " AND " + BEGIN + "=?"
2236 + " AND " + ALARM_TIME + "=?";
2237
2238 private static final String WHERE_FINDNEXTALARMTIME = ALARM_TIME + ">=?";
2239 private static final String SORT_ORDER_ALARMTIME_ASC = ALARM_TIME + " ASC";
2240
RoboErik083cd2d2011-06-30 11:53:05 -07002241 private static final String WHERE_RESCHEDULE_MISSED_ALARMS = STATE + "=" + STATE_SCHEDULED
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08002242 + " AND " + ALARM_TIME + "<?"
2243 + " AND " + ALARM_TIME + ">?"
2244 + " AND " + END + ">=?";
2245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002246 /**
2247 * This URI is for grouping the query results by event_id and begin
2248 * time. This will return one result per instance of an event. So
2249 * events with multiple alarms will appear just once, but multiple
2250 * instances of a repeating event will show up multiple times.
2251 */
Ken Shirriff5b387e12009-10-23 09:50:41 -07002252 public static final Uri CONTENT_URI_BY_INSTANCE =
Ken Shirriffa69a23b2010-01-21 17:32:39 -08002253 Uri.parse("content://" + AUTHORITY + "/calendar_alerts/by_instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254
RoboErik083cd2d2011-06-30 11:53:05 -07002255 private static final boolean DEBUG = false;
Michael Chancdaeafd2009-10-29 00:11:58 -07002256
RoboErikc2d53302011-06-03 09:37:58 -07002257 /**
RoboErik083cd2d2011-06-30 11:53:05 -07002258 * Helper for inserting an alarm time associated with an event TODO move
2259 * to Provider
RoboErikc2d53302011-06-03 09:37:58 -07002260 *
2261 * @hide
2262 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263 public static final Uri insert(ContentResolver cr, long eventId,
2264 long begin, long end, long alarmTime, int minutes) {
2265 ContentValues values = new ContentValues();
2266 values.put(CalendarAlerts.EVENT_ID, eventId);
2267 values.put(CalendarAlerts.BEGIN, begin);
2268 values.put(CalendarAlerts.END, end);
2269 values.put(CalendarAlerts.ALARM_TIME, alarmTime);
2270 long currentTime = System.currentTimeMillis();
2271 values.put(CalendarAlerts.CREATION_TIME, currentTime);
2272 values.put(CalendarAlerts.RECEIVED_TIME, 0);
2273 values.put(CalendarAlerts.NOTIFY_TIME, 0);
RoboErik083cd2d2011-06-30 11:53:05 -07002274 values.put(CalendarAlerts.STATE, STATE_SCHEDULED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 values.put(CalendarAlerts.MINUTES, minutes);
2276 return cr.insert(CONTENT_URI, values);
2277 }
2278
RoboErikc2d53302011-06-03 09:37:58 -07002279 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280 * Finds the next alarm after (or equal to) the given time and returns
RoboErikc2d53302011-06-03 09:37:58 -07002281 * the time of that alarm or -1 if no such alarm exists. This is a
RoboErik083cd2d2011-06-30 11:53:05 -07002282 * blocking call and should not be done on the UI thread. TODO move to
2283 * provider
Ken Shirriff5b387e12009-10-23 09:50:41 -07002284 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 * @param cr the ContentResolver
2286 * @param millis the time in UTC milliseconds
2287 * @return the next alarm time greater than or equal to "millis", or -1
RoboErikc2d53302011-06-03 09:37:58 -07002288 * if no such alarm exists.
RoboErik083cd2d2011-06-30 11:53:05 -07002289 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 */
2291 public static final long findNextAlarmTime(ContentResolver cr, long millis) {
2292 String selection = ALARM_TIME + ">=" + millis;
2293 // TODO: construct an explicit SQL query so that we can add
2294 // "LIMIT 1" to the end and get just one result.
2295 String[] projection = new String[] { ALARM_TIME };
RoboErik083cd2d2011-06-30 11:53:05 -07002296 Cursor cursor = cr.query(CONTENT_URI, projection, WHERE_FINDNEXTALARMTIME,
2297 (new String[] {
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08002298 Long.toString(millis)
RoboErik083cd2d2011-06-30 11:53:05 -07002299 }), SORT_ORDER_ALARMTIME_ASC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 long alarmTime = -1;
2301 try {
2302 if (cursor != null && cursor.moveToFirst()) {
2303 alarmTime = cursor.getLong(0);
2304 }
2305 } finally {
2306 if (cursor != null) {
2307 cursor.close();
2308 }
2309 }
2310 return alarmTime;
2311 }
Ken Shirriff5b387e12009-10-23 09:50:41 -07002312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 /**
2314 * Searches the CalendarAlerts table for alarms that should have fired
RoboErik083cd2d2011-06-30 11:53:05 -07002315 * but have not and then reschedules them. This method can be called at
2316 * boot time to restore alarms that may have been lost due to a phone
2317 * reboot. TODO move to provider
Ken Shirriff5b387e12009-10-23 09:50:41 -07002318 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 * @param cr the ContentResolver
2320 * @param context the Context
2321 * @param manager the AlarmManager
RoboErik083cd2d2011-06-30 11:53:05 -07002322 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 */
2324 public static final void rescheduleMissedAlarms(ContentResolver cr,
2325 Context context, AlarmManager manager) {
2326 // Get all the alerts that have been scheduled but have not fired
2327 // and should have fired by now and are not too old.
2328 long now = System.currentTimeMillis();
Michael Chancdaeafd2009-10-29 00:11:58 -07002329 long ancient = now - DateUtils.DAY_IN_MILLIS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 String[] projection = new String[] {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331 ALARM_TIME,
2332 };
Michael Chancdaeafd2009-10-29 00:11:58 -07002333
2334 // TODO: construct an explicit SQL query so that we can add
2335 // "GROUPBY" instead of doing a sort and de-dup
RoboErik083cd2d2011-06-30 11:53:05 -07002336 Cursor cursor = cr.query(CalendarAlerts.CONTENT_URI, projection,
2337 WHERE_RESCHEDULE_MISSED_ALARMS, (new String[] {
2338 Long.toString(now), Long.toString(ancient), Long.toString(now)
2339 }), SORT_ORDER_ALARMTIME_ASC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340 if (cursor == null) {
2341 return;
2342 }
Michael Chancdaeafd2009-10-29 00:11:58 -07002343
2344 if (DEBUG) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002345 Log.d(TAG, "missed alarms found: " + cursor.getCount());
2346 }
Ken Shirriff5b387e12009-10-23 09:50:41 -07002347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 try {
Michael Chancdaeafd2009-10-29 00:11:58 -07002349 long alarmTime = -1;
2350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 while (cursor.moveToNext()) {
Michael Chancdaeafd2009-10-29 00:11:58 -07002352 long newAlarmTime = cursor.getLong(0);
2353 if (alarmTime != newAlarmTime) {
2354 if (DEBUG) {
2355 Log.w(TAG, "rescheduling missed alarm. alarmTime: " + newAlarmTime);
2356 }
2357 scheduleAlarm(context, manager, newAlarmTime);
2358 alarmTime = newAlarmTime;
2359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002360 }
2361 } finally {
2362 cursor.close();
2363 }
Michael Chancdaeafd2009-10-29 00:11:58 -07002364 }
Ken Shirriff5b387e12009-10-23 09:50:41 -07002365
RoboErikc2d53302011-06-03 09:37:58 -07002366 /**
2367 * Schedules an alarm intent with the system AlarmManager that will
RoboErik3771fcb2011-06-16 15:41:31 -07002368 * notify listeners when a reminder should be fired. The provider will
2369 * keep scheduled reminders up to date but apps may use this to
2370 * implement snooze functionality without modifying the reminders table.
2371 * Scheduled alarms will generate an intent using
RoboErik083cd2d2011-06-30 11:53:05 -07002372 * {@link #ACTION_EVENT_REMINDER}. TODO Move to provider
RoboErikc2d53302011-06-03 09:37:58 -07002373 *
2374 * @param context A context for referencing system resources
2375 * @param manager The AlarmManager to use or null
2376 * @param alarmTime The time to fire the intent in UTC millis since
2377 * epoch
RoboErik083cd2d2011-06-30 11:53:05 -07002378 * @hide
RoboErikc2d53302011-06-03 09:37:58 -07002379 */
Michael Chancdaeafd2009-10-29 00:11:58 -07002380 public static void scheduleAlarm(Context context, AlarmManager manager, long alarmTime) {
2381 if (DEBUG) {
2382 Time time = new Time();
2383 time.set(alarmTime);
2384 String schedTime = time.format(" %a, %b %d, %Y %I:%M%P");
2385 Log.d(TAG, "Schedule alarm at " + alarmTime + " " + schedTime);
2386 }
2387
2388 if (manager == null) {
2389 manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
2390 }
2391
RoboErike00d5892011-06-23 15:16:55 -07002392 Intent intent = new Intent(ACTION_EVENT_REMINDER);
RoboErikbec6c362011-06-14 11:06:01 -07002393 intent.setData(ContentUris.withAppendedId(CalendarContract.CONTENT_URI, alarmTime));
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08002394 intent.putExtra(ALARM_TIME, alarmTime);
Erik42f19572010-03-17 16:17:22 -07002395 PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
Michael Chancdaeafd2009-10-29 00:11:58 -07002396 manager.set(AlarmManager.RTC_WAKEUP, alarmTime, pi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 }
Ken Shirriff5b387e12009-10-23 09:50:41 -07002398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 /**
RoboErik083cd2d2011-06-30 11:53:05 -07002400 * Searches for an entry in the CalendarAlerts table that matches the
2401 * given event id, begin time and alarm time. If one is found then this
2402 * alarm already exists and this method returns true. TODO Move to
2403 * provider
RoboErik58644022011-07-08 13:39:05 -07002404 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 * @param cr the ContentResolver
2406 * @param eventId the event id to match
2407 * @param begin the start time of the event in UTC millis
2408 * @param alarmTime the alarm time of the event in UTC millis
RoboErik083cd2d2011-06-30 11:53:05 -07002409 * @return true if there is already an alarm for the given event with
2410 * the same start time and alarm time.
2411 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002412 */
2413 public static final boolean alarmExists(ContentResolver cr, long eventId,
2414 long begin, long alarmTime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 // TODO: construct an explicit SQL query so that we can add
2416 // "LIMIT 1" to the end and get just one result.
Fabrice Di Meglio1dfc8a22010-03-10 17:49:46 -08002417 String[] projection = new String[] { ALARM_TIME };
RoboErik083cd2d2011-06-30 11:53:05 -07002418 Cursor cursor = cr.query(CONTENT_URI, projection, WHERE_ALARM_EXISTS,
2419 (new String[] {
2420 Long.toString(eventId), Long.toString(begin), Long.toString(alarmTime)
2421 }), null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422 boolean found = false;
2423 try {
2424 if (cursor != null && cursor.getCount() > 0) {
2425 found = true;
2426 }
2427 } finally {
2428 if (cursor != null) {
2429 cursor.close();
2430 }
2431 }
2432 return found;
2433 }
2434 }
2435
RoboErikf8143c52011-09-28 15:16:00 -07002436 protected interface ColorsColumns extends SyncStateContract.Columns {
2437
2438 /**
2439 * The type of color, which describes how it should be used. Valid types
2440 * are {@link #TYPE_CALENDAR} and {@link #TYPE_EVENT}. Column name.
2441 * <P>
2442 * Type: INTEGER (NOT NULL)
2443 * </P>
2444 */
2445 public static final String COLOR_TYPE = "color_type";
2446
2447 /**
2448 * This indicateds a color that can be used for calendars.
2449 */
2450 public static final int TYPE_CALENDAR = 0;
2451 /**
2452 * This indicates a color that can be used for events.
2453 */
2454 public static final int TYPE_EVENT = 1;
2455
2456 /**
RoboErik4172d952011-10-25 13:59:13 -07002457 * The key used to reference this color. This can be any non-empty
RoboErikf8143c52011-09-28 15:16:00 -07002458 * string, but must be unique for a given {@link #ACCOUNT_TYPE} and
RoboErik8a8eebc2011-10-20 16:57:18 -07002459 * {@link #ACCOUNT_NAME}. Column name.
RoboErikf8143c52011-09-28 15:16:00 -07002460 * <P>
2461 * Type: TEXT
2462 * </P>
2463 */
RoboErik4172d952011-10-25 13:59:13 -07002464 public static final String COLOR_KEY = "color_index";
RoboErikf8143c52011-09-28 15:16:00 -07002465
2466 /**
RoboErik05b36e52011-10-14 15:31:15 -07002467 * The color as an 8-bit ARGB integer value. Colors should specify alpha
2468 * as fully opaque (eg 0xFF993322) as the alpha may be ignored or
2469 * modified for display. It is reccomended that colors be usable with
2470 * light (near white) text. Apps should not depend on that assumption,
2471 * however. Column name.
RoboErikf8143c52011-09-28 15:16:00 -07002472 * <P>
2473 * Type: INTEGER (NOT NULL)
2474 * </P>
2475 */
RoboErik05b36e52011-10-14 15:31:15 -07002476 public static final String COLOR = "color";
RoboErikf8143c52011-09-28 15:16:00 -07002477
2478 }
2479
2480 /**
2481 * Fields for accessing colors available for a given account. Colors are
RoboErik4172d952011-10-25 13:59:13 -07002482 * referenced by {@link #COLOR_KEY} which must be unique for a given
RoboErik0c559c62011-10-21 11:20:51 -07002483 * account name/type. These values can only be updated by the sync
RoboErik8a8eebc2011-10-20 16:57:18 -07002484 * adapter. Only {@link #COLOR} may be updated after the initial insert. In
2485 * addition, a row can only be deleted once all references to that color
2486 * have been removed from the {@link Calendars} or {@link Events} tables.
RoboErikf8143c52011-09-28 15:16:00 -07002487 */
2488 public static final class Colors implements ColorsColumns {
2489 /**
2490 * @hide
2491 */
2492 public static final String TABLE_NAME = "Colors";
2493 /**
2494 * The Uri for querying color information
2495 */
2496 @SuppressWarnings("hiding")
2497 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/colors");
2498
2499 /**
2500 * This utility class cannot be instantiated
2501 */
2502 private Colors() {
2503 }
2504 }
2505
RoboErikb2c75602011-06-13 12:53:48 -07002506 protected interface ExtendedPropertiesColumns {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507 /**
RoboErikc2d53302011-06-03 09:37:58 -07002508 * The event the extended property belongs to. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 * <P>Type: INTEGER (foreign key to the Events table)</P>
2510 */
2511 public static final String EVENT_ID = "event_id";
2512
2513 /**
2514 * The name of the extended property. This is a uri of the form
RoboErikc2d53302011-06-03 09:37:58 -07002515 * {scheme}#{local-name} convention. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002516 * <P>Type: TEXT</P>
2517 */
2518 public static final String NAME = "name";
2519
2520 /**
RoboErikc2d53302011-06-03 09:37:58 -07002521 * The value of the extended property. Column name.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 * <P>Type: TEXT</P>
2523 */
2524 public static final String VALUE = "value";
2525 }
2526
RoboErikc2d53302011-06-03 09:37:58 -07002527 /**
2528 * Fields for accessing the Extended Properties. This is a generic set of
Michael Chan73bddfc2011-10-19 18:21:49 -07002529 * name/value pairs for use by sync adapters to add extra
RoboErik3771fcb2011-06-16 15:41:31 -07002530 * information to events. There are three writable columns and all three
2531 * must be present when inserting a new value. They are:
2532 * <ul>
2533 * <li>{@link #EVENT_ID}</li>
2534 * <li>{@link #NAME}</li>
2535 * <li>{@link #VALUE}</li>
2536 * </ul>
RoboErikc2d53302011-06-03 09:37:58 -07002537 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 public static final class ExtendedProperties implements BaseColumns,
2539 ExtendedPropertiesColumns, EventsColumns {
2540 public static final Uri CONTENT_URI =
Ken Shirriffa69a23b2010-01-21 17:32:39 -08002541 Uri.parse("content://" + AUTHORITY + "/extendedproperties");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542
RoboErik36726962011-06-14 14:01:15 -07002543 /**
2544 * This utility class cannot be instantiated
2545 */
2546 private ExtendedProperties() {}
2547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002548 // TODO: fill out this class when we actually start utilizing extendedproperties
2549 // in the calendar application.
2550 }
Ken Shirriffead4f9c2010-01-22 12:26:02 -08002551
2552 /**
2553 * A table provided for sync adapters to use for storing private sync state data.
2554 *
2555 * @see SyncStateContract
2556 */
2557 public static final class SyncState implements SyncStateContract.Columns {
2558 /**
2559 * This utility class cannot be instantiated
2560 */
2561 private SyncState() {}
2562
RoboErikc2d53302011-06-03 09:37:58 -07002563 private static final String CONTENT_DIRECTORY =
Ken Shirriffead4f9c2010-01-22 12:26:02 -08002564 SyncStateContract.Constants.CONTENT_DIRECTORY;
2565
2566 /**
2567 * The content:// style URI for this table
2568 */
2569 public static final Uri CONTENT_URI =
RoboErikbec6c362011-06-14 11:06:01 -07002570 Uri.withAppendedPath(CalendarContract.CONTENT_URI, CONTENT_DIRECTORY);
Ken Shirriffead4f9c2010-01-22 12:26:02 -08002571 }
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002572
2573 /**
2574 * Columns from the EventsRawTimes table
RoboErik3771fcb2011-06-16 15:41:31 -07002575 *
2576 * @hide
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002577 */
RoboErikb2c75602011-06-13 12:53:48 -07002578 protected interface EventsRawTimesColumns {
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002579 /**
RoboErikc2d53302011-06-03 09:37:58 -07002580 * The corresponding event id. Column name.
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002581 * <P>Type: INTEGER (long)</P>
2582 */
2583 public static final String EVENT_ID = "event_id";
2584
2585 /**
RoboErikc2d53302011-06-03 09:37:58 -07002586 * The RFC2445 compliant time the event starts. Column name.
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002587 * <P>Type: TEXT</P>
2588 */
2589 public static final String DTSTART_2445 = "dtstart2445";
2590
2591 /**
RoboErikc2d53302011-06-03 09:37:58 -07002592 * The RFC2445 compliant time the event ends. Column name.
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002593 * <P>Type: TEXT</P>
2594 */
2595 public static final String DTEND_2445 = "dtend2445";
2596
2597 /**
RoboErikc2d53302011-06-03 09:37:58 -07002598 * The RFC2445 compliant original instance time of the recurring event
2599 * for which this event is an exception. Column name.
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002600 * <P>Type: TEXT</P>
2601 */
2602 public static final String ORIGINAL_INSTANCE_TIME_2445 = "originalInstanceTime2445";
2603
2604 /**
RoboErikc2d53302011-06-03 09:37:58 -07002605 * The RFC2445 compliant last date this event repeats on, or NULL if it
2606 * never ends. Column name.
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002607 * <P>Type: TEXT</P>
2608 */
2609 public static final String LAST_DATE_2445 = "lastDate2445";
2610 }
2611
RoboErikc2d53302011-06-03 09:37:58 -07002612 /**
2613 * @hide
2614 */
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002615 public static final class EventsRawTimes implements BaseColumns, EventsRawTimesColumns {
RoboErik36726962011-06-14 14:01:15 -07002616
2617 /**
2618 * This utility class cannot be instantiated
2619 */
2620 private EventsRawTimes() {}
Fabrice Di Meglio50563552010-06-15 16:35:20 -07002621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622}