Skip to content

Commit

Permalink
Merge pull request #9 from jamesmontemagno/master
Browse files Browse the repository at this point in the history
Ability to set location, add reminder, and set android calendar to sync. Also fixes #10 by creating iCloud calendars instead of local calendars if iCloud is enabled.
  • Loading branch information
TheAlmightyBob committed Feb 15, 2016
2 parents 8c5b9e0 + 2b9d311 commit 6b547b0
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 19 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ build/
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

*.lock.json

*_i.c
*_p.c
*.ilk
Expand Down
9 changes: 8 additions & 1 deletion Calendars.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calendars.Plugin", "Calendars\Calendars.Plugin\Calendars.Plugin.csproj", "{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}"
EndProject
Expand Down Expand Up @@ -104,6 +104,7 @@ Global
{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}.Debug|ARM.ActiveCfg = Debug|Any CPU
{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}.Debug|iPhone.Build.0 = Debug|Any CPU
{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{A6FCEF44-D2BA-42C7-B3CB-13667BCD7B54}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -148,6 +149,7 @@ Global
{6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}.Debug|iPhone.Build.0 = Debug|Any CPU
{6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -191,6 +193,7 @@ Global
{D7F3AA16-8EF1-4924-9E0A-DAD4AB46B2EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7F3AA16-8EF1-4924-9E0A-DAD4AB46B2EB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D7F3AA16-8EF1-4924-9E0A-DAD4AB46B2EB}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{D7F3AA16-8EF1-4924-9E0A-DAD4AB46B2EB}.Debug|iPhone.Build.0 = Debug|Any CPU
{D7F3AA16-8EF1-4924-9E0A-DAD4AB46B2EB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D7F3AA16-8EF1-4924-9E0A-DAD4AB46B2EB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{D7F3AA16-8EF1-4924-9E0A-DAD4AB46B2EB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -233,6 +236,7 @@ Global
{2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}.Debug|iPhone.Build.0 = Debug|Any CPU
{2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -273,6 +277,7 @@ Global
{56A56F17-7DE1-4CA1-9617-BF32E971AC84}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{56A56F17-7DE1-4CA1-9617-BF32E971AC84}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{56A56F17-7DE1-4CA1-9617-BF32E971AC84}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{56A56F17-7DE1-4CA1-9617-BF32E971AC84}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{56A56F17-7DE1-4CA1-9617-BF32E971AC84}.Debug|x64.ActiveCfg = Debug|Any CPU
{56A56F17-7DE1-4CA1-9617-BF32E971AC84}.Debug|x86.ActiveCfg = Debug|Any CPU
{56A56F17-7DE1-4CA1-9617-BF32E971AC84}.Release|Android.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -717,6 +722,8 @@ Global
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Debug|x64.ActiveCfg = Debug|Any CPU
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Debug|x86.ActiveCfg = Debug|Any CPU
{E6284EB0-BDB0-4D38-AFC4-ECDC7BFF6D6E}.Release|Android.ActiveCfg = Release|Any CPU
Expand Down
8 changes: 7 additions & 1 deletion Calendars/Calendars.Plugin.Abstractions/CalendarEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public class CalendarEvent
/// </summary>
public DateTime End { get; set; }

/// <summary>
/// Gets or sets the location of the event
/// </summary>
public string Location { get; set; }

/// <summary>
/// Whether or not this is an "all-day" event.
/// </summary>
Expand All @@ -42,14 +47,15 @@ public class CalendarEvent
/// </summary>
/// <remarks>This ID will be the same for each instance of a recurring event.</remarks>
public string ExternalID { get; set; }


/// <summary>
/// Simple ToString helper, to assist with debugging.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "Name=" + Name + ", AllDay=" + AllDay + ", Start=" + Start + ", End=" + End;
return "Name=" + Name + ", AllDay=" + AllDay + ", Start=" + Start + ", End=" + End + ", Location=" + Location;
}
}
}
49 changes: 49 additions & 0 deletions Calendars/Calendars.Plugin.Abstractions/CalendarEventReminder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Calendars.Plugin.Abstractions
{
/// <summary>
/// Calendar reminder that happens before the event such as an alert
/// </summary>
public class CalendarEventReminder
{

/// <summary>
/// Amount of time to set the reminder before the start of an event.
/// Default is 15 minutes
/// </summary>
public TimeSpan TimeBefore { get; set; } = TimeSpan.FromMinutes(15);
/// <summary>
/// Type of reminder to display
/// </summary>
public CalendarReminderMethod Method { get; set; } = CalendarReminderMethod.Default;

}

/// <summary>
/// Types of methods of the reminder
/// </summary>
public enum CalendarReminderMethod
{
/// <summary>
/// Use system default
/// </summary>
Default,
/// <summary>
/// Pop up alert
/// </summary>
Alert,
/// <summary>
/// Send an email
/// </summary>
Email,
/// <summary>
/// Send an sms
/// </summary>
Sms
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<ItemGroup>
<Compile Include="Calendar.cs" />
<Compile Include="CalendarEvent.cs" />
<Compile Include="CalendarEventReminder.cs" />
<Compile Include="ICalendars.cs" />
<Compile Include="ICalendarsExtensions.cs" />
<Compile Include="PlatformException.cs" />
Expand Down
10 changes: 10 additions & 0 deletions Calendars/Calendars.Plugin.Abstractions/ICalendars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,15 @@ public interface ICalendars
/// <exception cref="System.UnauthorizedAccessException">Calendar access denied</exception>
/// <exception cref="Calendars.Plugin.Abstractions.PlatformException">Unexpected platform-specific error</exception>
Task<bool> DeleteEventAsync(Calendar calendar, CalendarEvent calendarEvent);

/// <summary>
/// Adds a reminder to the specified calendar event
/// </summary>
/// <param name="calendarEvent">Event to add</param>
/// <param name="reminder">Reminder to add</param>
/// <returns>If successful</returns>
/// <exception cref="ArgumentException">If calendar event is not created or not valid</exception>
/// <exception cref="Calendars.Plugin.Abstractions.PlatformException">Unexpected platform-specific error</exception>
Task<bool> AddEventReminderAsync(CalendarEvent calendarEvent, CalendarEventReminder reminder);
}
}
62 changes: 61 additions & 1 deletion Calendars/Calendars.Plugin.Android/CalendarsImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ public async Task<IList<CalendarEvent>> GetEventsAsync(Calendar calendar, DateTi
CalendarContract.Events.InterfaceConsts.Dtstart,
CalendarContract.Events.InterfaceConsts.Dtend,
CalendarContract.Events.InterfaceConsts.AllDay,
CalendarContract.Events.InterfaceConsts.EventLocation,
CalendarContract.Instances.EventId
};

Expand Down Expand Up @@ -204,6 +205,7 @@ await Task.Run(() =>
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());
Expand Down Expand Up @@ -241,6 +243,7 @@ public Task<CalendarEvent> GetEventByIdAsync(string externalId)
CalendarContract.Events.InterfaceConsts.Description,
CalendarContract.Events.InterfaceConsts.Dtstart,
CalendarContract.Events.InterfaceConsts.Dtend,
CalendarContract.Events.InterfaceConsts.EventLocation,
CalendarContract.Events.InterfaceConsts.AllDay
};

Expand All @@ -262,6 +265,7 @@ public Task<CalendarEvent> GetEventByIdAsync(string externalId)
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)
};
}
Expand Down Expand Up @@ -333,6 +337,7 @@ public async Task AddOrUpdateCalendarAsync(Calendar calendar)
values.Put(CalendarContract.Calendars.InterfaceConsts.AccountName, AccountName);
values.Put(CalendarContract.Calendars.InterfaceConsts.OwnerAccount, OwnerAccount);
values.Put(CalendarContract.Calendars.InterfaceConsts.Visible, true);
values.Put(CalendarContract.Calendars.InterfaceConsts.SyncEvents, true);

values.Put(CalendarContract.Calendars.InterfaceConsts.AccountType, CalendarContract.AccountTypeLocal);
}
Expand Down Expand Up @@ -421,6 +426,8 @@ await Task.Run(() =>
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);
Expand All @@ -435,7 +442,60 @@ await Task.Run(() =>
}
});
}

/// <summary>
/// Adds an event reminder to specified calendar event
/// </summary>
/// <param name="calendarEvent">Event to add the reminder to</param>
/// <param name="reminder">The reminder</param>
/// <returns>Success or failure</returns>
/// <exception cref="ArgumentException">If calendar event is not created or not valid</exception>
/// <exception cref="Calendars.Plugin.Abstractions.PlatformException">Unexpected platform-specific error</exception>
public async Task<bool> AddEventReminderAsync(CalendarEvent calendarEvent, CalendarEventReminder reminder)
{
if (string.IsNullOrEmpty(calendarEvent.ExternalID))
{
throw new ArgumentException("Missing calendar event identifier", "calendarEvent");
}
// Verify calendar event exists
var existingAppt = await GetEventByIdAsync(calendarEvent.ExternalID).ConfigureAwait(false);

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

return await Task.Run(() =>
{
var reminderValues = new ContentValues();
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Minutes, reminder?.TimeBefore.TotalMinutes ?? 15);
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.EventId, calendarEvent.ExternalID);
switch(reminder.Method)
{
case CalendarReminderMethod.Alert:
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Method, (int)RemindersMethod.Alert);
break;
case CalendarReminderMethod.Default:
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Method, (int)RemindersMethod.Default);
break;
case CalendarReminderMethod.Email:
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Method, (int)RemindersMethod.Email);
break;
case CalendarReminderMethod.Sms:
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Method, (int)RemindersMethod.Sms);
break;

}
var uri = CalendarContract.Reminders.ContentUri;
Insert(uri, reminderValues);


return true;
});

}


/// <summary>
/// Removes a calendar and all its events from the system.
/// </summary>
Expand Down Expand Up @@ -638,4 +698,4 @@ private static Exception TranslateException(Java.Lang.Exception ex)

#endregion
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static CalendarEvent ToCalendarEvent(this Appointment appt)
Start = appt.StartTime.LocalDateTime,
End = appt.StartTime.Add(appt.Duration).LocalDateTime,
AllDay = appt.AllDay,
Location = appt.Location,
ExternalID = appt.LocalId
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public async Task<IList<CalendarEvent>> GetEventsAsync(Calendar calendar, DateTi
options.FetchProperties.Add(AppointmentProperties.StartTime);
options.FetchProperties.Add(AppointmentProperties.Duration);
options.FetchProperties.Add(AppointmentProperties.AllDay);
options.FetchProperties.Add(AppointmentProperties.Location);

var appointments = await deviceCalendar.FindAppointmentsAsync(start, end - start, options).ConfigureAwait(false);
var events = appointments.Select(a => a.ToCalendarEvent()).ToList();
Expand Down Expand Up @@ -227,12 +228,52 @@ public async Task AddOrUpdateEventAsync(Calendar calendar, CalendarEvent calenda
appt.StartTime = calendarEvent.Start;
appt.Duration = calendarEvent.End - calendarEvent.Start;
appt.AllDay = calendarEvent.AllDay;
appt.Location = calendarEvent.Location ?? string.Empty;

await appCalendar.SaveAppointmentAsync(appt);

calendarEvent.ExternalID = appt.LocalId;
}

/// <summary>
/// Adds an event reminder to specified calendar event
/// </summary>
/// <param name="calendarEvent">Event to add the reminder to</param>
/// <param name="reminder">The reminder</param>
/// <returns>Success or failure</returns>
/// <exception cref="ArgumentException">If calendar event is not created or not valid</exception>
/// <exception cref="Calendars.Plugin.Abstractions.PlatformException">Unexpected platform-specific error</exception>
public async Task<bool> AddEventReminderAsync(CalendarEvent calendarEvent, CalendarEventReminder reminder)
{
if (string.IsNullOrEmpty(calendarEvent.ExternalID))
{
throw new ArgumentException("Missing calendar event identifier", "calendarEvent");
}


var existingAppt = await _localApptStore.GetAppointmentAsync(calendarEvent.ExternalID);


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


var appCalendar = await _localApptStore.GetAppointmentCalendarAsync(existingAppt.CalendarId);

if(appCalendar == null)
{
throw new ArgumentException("Event does not have a valid calendar.");
}

existingAppt.Reminder = reminder?.TimeBefore ?? TimeSpan.FromMinutes(15);

await appCalendar.SaveAppointmentAsync(existingAppt);

return true;
}

/// <summary>
/// Removes a calendar and all its events from the system.
/// </summary>
Expand Down Expand Up @@ -335,9 +376,9 @@ public async Task<bool> DeleteEventAsync(Calendar calendar, CalendarEvent calend
return deleted;
}

#endregion
#endregion

#region Private Methods
#region Private Methods

private async Task EnsureInitializedAsync()
{
Expand Down Expand Up @@ -422,4 +463,4 @@ private async Task<AppointmentCalendar> GetLocalCalendarAsync(string id)

#endregion
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,15 @@ public Task AddOrUpdateEventAsync(Calendar calendar, CalendarEvent calendarEvent
/// <summary>
/// Not supported for Windows Store apps
/// </summary>
public Task<bool> DeleteCalendarAsync(Calendar calendar)
public Task<bool> AddEventReminderAsync(CalendarEvent calendarEvent, CalendarEventReminder reminder)
{
throw new NotSupportedException();
}

/// <summary>
/// Not supported for Windows Store apps
/// </summary>
public Task<bool> DeleteCalendarAsync(Calendar calendar)
{
throw new NotSupportedException();
}
Expand Down
Loading

0 comments on commit 6b547b0

Please sign in to comment.