Example #1
0
        /// <summary>
        /// Gets all events for a calendar within the specified time range.
        /// </summary>
        /// <param name="calendar">Calendar containing events</param>
        /// <param name="start">Start of event range</param>
        /// <param name="end">End of event range</param>
        /// <returns>Calendar events</returns>
        /// <exception cref="System.ArgumentException">Calendar does not exist on device</exception>
        /// <exception cref="System.UnauthorizedAccessException">Calendar access denied</exception>
        /// <exception cref="Plugin.Calendars.Abstractions.PlatformException">Unexpected platform-specific error</exception>
        public async Task <IList <CalendarEvent> > GetEventsAsync(Calendar calendar, DateTime start, DateTime end)
        {
            var deviceCalendar = await GetCalendarByIdAsync(calendar.ExternalID).ConfigureAwait(false);

            if (deviceCalendar == null)
            {
                throw new ArgumentException("Specified calendar not found on device");
            }

            var eventsUriBuilder = CalendarContract.Instances.ContentUri.BuildUpon();

            // Note that this is slightly different from the GetEventById projection
            // due to the Instances API vs. Event API (specifically, IDs and start/end times)
            //
            string[] eventsProjection =
            {
                CalendarContract.Events.InterfaceConsts.Title,
                CalendarContract.Events.InterfaceConsts.Description,
                CalendarContract.Instances.Begin,
                CalendarContract.Instances.End,
                CalendarContract.Events.InterfaceConsts.AllDay,
                CalendarContract.Events.InterfaceConsts.EventLocation,
                CalendarContract.Instances.EventId
            };

            ContentUris.AppendId(eventsUriBuilder, DateConversions.GetDateAsAndroidMS(start));
            ContentUris.AppendId(eventsUriBuilder, DateConversions.GetDateAsAndroidMS(end));
            var eventsUri = eventsUriBuilder.Build();

            return(await Task.Run(() =>
            {
                var cursor = Query(eventsUri, eventsProjection,
                                   string.Format("{0} = {1}", CalendarContract.Events.InterfaceConsts.CalendarId, calendar.ExternalID),
                                   null, CalendarContract.Events.InterfaceConsts.Dtstart + " ASC");

                var events = IterateCursor(cursor, () =>
                {
                    bool allDay = cursor.GetBoolean(CalendarContract.Events.InterfaceConsts.AllDay);

                    var calendarEvent = new CalendarEvent
                    {
                        Name = cursor.GetString(CalendarContract.Events.InterfaceConsts.Title),
                        ExternalID = cursor.GetString(CalendarContract.Instances.EventId),
                        Description = cursor.GetString(CalendarContract.Events.InterfaceConsts.Description),
                        Start = cursor.GetDateTime(CalendarContract.Instances.Begin, allDay),
                        End = cursor.GetDateTime(CalendarContract.Instances.End, allDay),
                        Location = cursor.GetString(CalendarContract.Events.InterfaceConsts.EventLocation),
                        AllDay = allDay
                    };
                    calendarEvent.Reminders = GetEventReminders(calendarEvent.ExternalID);

                    return calendarEvent;
                });

                return events;
            }).ConfigureAwait(false));
        }
Example #2
0
        /// <summary>
        /// Returns the value of the requested column as a DateTime
        /// </summary>
        /// <returns>The DateTime.</returns>
        /// <param name="cursor">Cursor.</param>
        /// <param name="column">Column name.</param>
        /// <param name="allDay">Whether the event is all-day</param>
        public static DateTime GetDateTime(this ICursor cursor, string column, bool allDay)
        {
            var ms = cursor.GetLong(cursor.GetColumnIndex(column));

            var dt = DateConversions.GetDateFromAndroidMS(ms);

            // All day events should not be affected by time zones, so we simply take the
            // UTC time and treat it as local (e.g., Christmas doesn't start on the 24th in California...)
            //
            return(allDay ? DateTime.SpecifyKind(dt.ToUniversalTime(), DateTimeKind.Local) : dt.ToLocalTime());
        }
Example #3
0
        /// <summary>
        /// Add new event to a calendar or update an existing event.
        /// </summary>
        /// <param name="calendar">Destination calendar</param>
        /// <param name="calendarEvent">Event to add or update</param>
        /// <exception cref="System.ArgumentException">Calendar is not specified, does not exist on device, or is read-only</exception>
        /// <exception cref="System.UnauthorizedAccessException">Calendar access denied</exception>
        /// <exception cref="Calendars.Plugin.Abstractions.PlatformException">Unexpected platform-specific error</exception>
        public async Task AddOrUpdateEventAsync(Calendar calendar, CalendarEvent calendarEvent)
        {
            if (string.IsNullOrEmpty(calendar.ExternalID))
            {
                throw new ArgumentException("Missing calendar identifier", "calendar");
            }
            else
            {
                // Verify calendar exists (Android actually allows using a nonexistent calendar ID...)
                //
                var deviceCalendar = await GetCalendarByIdAsync(calendar.ExternalID).ConfigureAwait(false);

                if (deviceCalendar == null)
                {
                    throw new ArgumentException("Specified calendar not found on device");
                }
            }

            // Validate times
            if (calendarEvent.End < calendarEvent.Start)
            {
                throw new ArgumentException("End time may not precede start time", "calendarEvent");
            }

            bool updateExisting = false;
            long existingId     = -1;

            await Task.Run(() =>
            {
                if (long.TryParse(calendarEvent.ExternalID, out existingId))
                {
                    var calendarId = GetCalendarIdForEventId(calendarEvent.ExternalID);

                    if (calendarId.HasValue && calendarId.Value.ToString() == calendar.ExternalID)
                    {
                        updateExisting = true;
                    }
                }

                var eventValues = new ContentValues();

                eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId,
                                calendar.ExternalID);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Title,
                                calendarEvent.Name);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Description,
                                calendarEvent.Description);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart,
                                DateConversions.GetDateAsAndroidMS(calendarEvent.Start));
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend,
                                DateConversions.GetDateAsAndroidMS(calendarEvent.End));
                eventValues.Put(CalendarContract.Events.InterfaceConsts.AllDay,
                                calendarEvent.AllDay);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.EventLocation,
                                calendarEvent.Location ?? string.Empty);

                eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone,
                                Java.Util.TimeZone.Default.ID);

                if (!updateExisting)
                {
                    calendarEvent.ExternalID = Insert(_eventsUri, eventValues);
                }
                else
                {
                    Update(_eventsUri, existingId, eventValues);
                }
            });
        }
Example #4
0
        /// <summary>
        /// Gets all events for a calendar within the specified time range.
        /// </summary>
        /// <param name="calendar">Calendar containing events</param>
        /// <param name="start">Start of event range</param>
        /// <param name="end">End of event range</param>
        /// <returns>Calendar events</returns>
        /// <exception cref="System.ArgumentException">Calendar does not exist on device</exception>
        /// <exception cref="System.UnauthorizedAccessException">Calendar access denied</exception>
        /// <exception cref="Calendars.Plugin.Abstractions.PlatformException">Unexpected platform-specific error</exception>
        public async Task <IList <CalendarEvent> > GetEventsAsync(Calendar calendar, DateTime start, DateTime end)
        {
            var deviceCalendar = await GetCalendarByIdAsync(calendar.ExternalID).ConfigureAwait(false);

            if (deviceCalendar == null)
            {
                throw new ArgumentException("Specified calendar not found on device");
            }

            var eventsUriBuilder = CalendarContract.Instances.ContentUri.BuildUpon();

            // Note that this is slightly different from the GetEventById projection
            // due to the Instances API vs. Event API (specifically, IDs)
            //
            string[] eventsProjection =
            {
//                CalendarContract.Events.InterfaceConsts.Id,
                CalendarContract.Events.InterfaceConsts.Title,
                CalendarContract.Events.InterfaceConsts.Description,
                CalendarContract.Events.InterfaceConsts.Dtstart,
                CalendarContract.Events.InterfaceConsts.Dtend,
                CalendarContract.Events.InterfaceConsts.AllDay,
                CalendarContract.Events.InterfaceConsts.EventLocation,
                CalendarContract.Instances.EventId
            };

            ContentUris.AppendId(eventsUriBuilder, DateConversions.GetDateAsAndroidMS(start));
            ContentUris.AppendId(eventsUriBuilder, DateConversions.GetDateAsAndroidMS(end));
            var eventsUri = eventsUriBuilder.Build();
            var events    = new List <CalendarEvent>();

            await Task.Run(() =>
            {
                var cursor = Query(eventsUri, eventsProjection,
                                   string.Format("{0} = {1}", CalendarContract.Events.InterfaceConsts.CalendarId, calendar.ExternalID),
                                   null, CalendarContract.Events.InterfaceConsts.Dtstart + " ASC");

                try
                {
                    if (cursor.MoveToFirst())
                    {
                        do
                        {
                            events.Add(new CalendarEvent
                            {
                                Name        = cursor.GetString(CalendarContract.Events.InterfaceConsts.Title),
                                ExternalID  = cursor.GetString(CalendarContract.Instances.EventId),
                                Description = cursor.GetString(CalendarContract.Events.InterfaceConsts.Description),
                                Start       = cursor.GetDateTime(CalendarContract.Events.InterfaceConsts.Dtstart),
                                End         = cursor.GetDateTime(CalendarContract.Events.InterfaceConsts.Dtend),
                                Location    = cursor.GetString(CalendarContract.Events.InterfaceConsts.EventLocation),
                                AllDay      = cursor.GetBoolean(CalendarContract.Events.InterfaceConsts.AllDay)
                            });
                        } while (cursor.MoveToNext());
                    }
                }
                catch (Java.Lang.Exception ex)
                {
                    throw new PlatformException(ex.Message, ex);
                }
                finally
                {
                    cursor.Close();
                }
            });

            return(events);
        }
        /// <summary>
        /// Add new event to a calendar or update an existing event.
        /// If a new event was added, the ExternalID property will be set on the CalendarEvent object,
        /// to support future queries/updates.
        /// </summary>
        /// <param name="calendar">Destination calendar</param>
        /// <param name="calendarEvent">Event to add or update</param>
        /// <exception cref="System.ArgumentException">Calendar is not specified, does not exist on device, or is read-only</exception>
        /// <exception cref="System.UnauthorizedAccessException">Calendar access denied</exception>
        /// <exception cref="System.InvalidOperationException">Editing recurring events is not supported</exception>
        /// <exception cref="Plugin.Calendars.Abstractions.PlatformException">Unexpected platform-specific error</exception>
        public async Task AddOrUpdateEventAsync(Calendar calendar, CalendarEvent calendarEvent)
        {
            if (string.IsNullOrEmpty(calendar.ExternalID))
            {
                throw new ArgumentException("Missing calendar identifier", "calendar");
            }
            else
            {
                // Verify calendar exists (Android actually allows using a nonexistent calendar ID...)
                //
                var deviceCalendar = await GetCalendarByIdAsync(calendar.ExternalID).ConfigureAwait(false);

                if (deviceCalendar == null)
                {
                    throw new ArgumentException("Specified calendar not found on device");
                }
            }

            // Validate times
            if (calendarEvent.End < calendarEvent.Start)
            {
                throw new ArgumentException("End time may not precede start time", "calendarEvent");
            }

            bool          updateExisting = false;
            long          existingId     = -1;
            CalendarEvent existingEvent  = null;

            await Task.Run(() =>
            {
                if (long.TryParse(calendarEvent.ExternalID, out existingId))
                {
                    if (IsEventRecurring(calendarEvent.ExternalID))
                    {
                        throw new InvalidOperationException("Editing recurring events is not supported");
                    }

                    var calendarId = GetCalendarIdForEventId(calendarEvent.ExternalID);

                    if (calendarId.HasValue && calendarId.Value.ToString() == calendar.ExternalID)
                    {
                        updateExisting = true;
                        existingEvent  = GetEventById(calendarEvent.ExternalID);
                    }
                }

                var eventValues = new ContentValues();
                bool allDay     = calendarEvent.AllDay;
                var start       = allDay
                        ? DateTime.SpecifyKind(calendarEvent.Start.Date, DateTimeKind.Utc)
                        : calendarEvent.Start;
                var end = allDay
                        ? DateTime.SpecifyKind(calendarEvent.End.Date, DateTimeKind.Utc)
                        : calendarEvent.End;

                eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId,
                                calendar.ExternalID);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Title,
                                calendarEvent.Name);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Description,
                                calendarEvent.Description);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart,
                                DateConversions.GetDateAsAndroidMS(start));
                eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend,
                                DateConversions.GetDateAsAndroidMS(end));
                eventValues.Put(CalendarContract.Events.InterfaceConsts.AllDay,
                                allDay);
                eventValues.Put(CalendarContract.Events.InterfaceConsts.EventLocation,
                                calendarEvent.Location ?? string.Empty);

                // If we're updating an existing event, don't mess with the existing
                // time zone (since we don't support explicitly setting it yet).
                // *Unless* we're toggling the "all day" setting
                // (because that would mean the time zone is UTC rather than local...).
                //
                if (!updateExisting || allDay != existingEvent?.AllDay)
                {
                    eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone,
                                    allDay
                            ? Java.Util.TimeZone.GetTimeZone("UTC")?.ID ?? string.Empty
                            : Java.Util.TimeZone.Default.ID);
                }

                if (!updateExisting)
                {
                    calendarEvent.ExternalID = Insert(_eventsUri, eventValues);
                }
                else
                {
                    Update(_eventsUri, existingId, eventValues);
                }
            }).ConfigureAwait(false);
        }
Example #6
0
        /// <summary>
        /// Returns the value of the requested column as a DateTime
        /// </summary>
        /// <returns>The DateTime.</returns>
        /// <param name="cursor">Cursor.</param>
        /// <param name="column">Column name.</param>
        public static DateTime GetDateTime(this ICursor cursor, string column)
        {
            var ms = cursor.GetLong(cursor.GetColumnIndex(column));

            return(DateConversions.GetDateFromAndroidMS(ms));
        }