This project is a Calendar Service for Android and has been born since I was in need of a service which returned events from all the calendars embedded on an Android Smartphone in a specific timerange.
Hereby, the service basically returns a list which contains the id of a specific calendar and the events of the specific calendar.
You can either find the code repository on GitHub, or simply copy-paste the code below.
Please note that the repository is licensed under the Apache License, Version 2.0.
Basic use
Before going into too many details regarding the service itself, I will first of all show you how to use the library.
The code below essentially specifies how the library is intended to be taken into use:
1 2 3 4 5 6 7 8 9 10 11 12 |
// The basic constructor will return a time range of +/- 1 day CalendarService.readCalendar(MainActivity.this); // Please note that MainActivity.this should be replaced with your own class name or context // If required, you can specify the required time range: CalendarService.readCalendar(MainActivity.this, int days, int hours); // An example can be seen below: CalendarService.readCalendar(MainActivity.this, 2, 5); // The example as seen above returns a list of events +/- 2 days and +/- 5 hours respecitvely |
As seen, the use of the service is quite basic and can be used for many different purposes such as returning a list of events upon clicking a button.
Although, the service may still not be working as expected, which can be due to missing permissions. For that reason, include the following snippet in AndroidManifest.XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.calendarservice" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_CALENDAR"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > </application> </manifest> |
By now, you should be able to access the calendars on the phone and read the events hereof.
Implementation
Since that you by now understand the overall purpose of the service, I will by now provide the actual implementation which consits of two classes:
- The CalendarEvent class which is essentially an object of a calendar event
- The CalendarService which creates a list of calendar events related to a specific calendar
- If several calendars exist on the phone (which are not empty), the list will by then contain several calendar IDs which each will contain a list of calendar events
I will start of showing the most basic details, and go into the specifics as we move along.
The Calandar Object (CalendarEvent)
First of all, a Calendar Event (i.e. an object) basically contains the following information:
- A title which contains the description of the event
- The begin (start) date of the event which contains the day, the month, the date, the time, the timezone and the year
- The end date of the event which contains the same information as above
- Whether or not it is an all day event
The code of how a Calendar Event is implemented can be seen below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
import java.util.Date; /* * Created by David Laundav and contributed by Christian Orthmann * * Copyright 2013 Daivd Laundav * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ public class CalendarEvent implements Comparable<CalendarEvent>{ private String title; private Date begin, end; private boolean allDay; public CalendarEvent() { } public CalendarEvent(String title, Date begin, Date end, boolean allDay) { setTitle(title); setBegin(begin); setEnd(end); setAllDay(allDay); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Date getBegin() { return begin; } public void setBegin(Date begin) { this.begin = begin; } public Date getEnd() { return end; } public void setEnd(Date end) { this.end = end; } public boolean isAllDay() { return allDay; } public void setAllDay(boolean allDay) { this.allDay = allDay; } @Override public String toString(){ return getTitle() + " " + getBegin() + " " + getEnd() + " " + isAllDay(); } @Override public int compareTo(CalendarEvent other) { // -1 = less, 0 = equal, 1 = greater return getBegin().compareTo(other.begin); } } |
The Calendar Service (CalendarService)
The specific implementation details of the Calendar Service itself is – in comparison with a Calendar Event as seen above – although much more difficult to explain in brief.
Although, the basic purpose is, that the Calendar Service provides a hash map where each Calendar ID (which contain events) is mapped with its Calendar Events.
Hereby, the implementation details are provided as a part of the source code itself in form of comments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.text.format.DateUtils; /* * Created by David Laundav and contributed by Christian Orthmann * * Copyright 2013 Daivd Laundav * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * References: * http://stackoverflow.com/questions/5883938/getting-events-from-calendar * * Please do not delete the references as they gave inspiration for the implementation */ public class CalendarService { // Default constructor public static void readCalendar(Context context) { readCalendar(context, 1, 0); } // Use to specify specific the time span public static void readCalendar(Context context, int days, int hours) { ContentResolver contentResolver = context.getContentResolver(); // Create a cursor and read from the calendar final Cursor cursor = contentResolver.query(Uri.parse("content://com.android.calendar/calendars"), (new String[] { "_id", "displayName", "selected" }), null, null, null); // Create a set containing all of the calendar IDs available on the phone HashSet<String> calendarIds = getCalenderIds(cursor); // Create a hash map of calendar ids and the events of each id HashMap<String, List<CalendarEvent>> eventMap = new HashMap<String, List<CalendarEvent>>(); // Loop over all of the calendars for (String id : calendarIds) { // Create a builder to define the time span Uri.Builder builder = Uri.parse("content://com.android.calendar/instances/when").buildUpon(); long now = new Date().getTime(); // create the time span based on the inputs ContentUris.appendId(builder, now - (DateUtils.DAY_IN_MILLIS * days) - (DateUtils.HOUR_IN_MILLIS * hours)); ContentUris.appendId(builder, now + (DateUtils.DAY_IN_MILLIS * days) + (DateUtils.HOUR_IN_MILLIS * hours)); // Create an event cursor to find all events in the calendar Cursor eventCursor = contentResolver.query(builder.build(), new String[] { "title", "begin", "end", "allDay"}, "Calendars._id=" + id, null, "startDay ASC, startMinute ASC"); System.out.println("eventCursor count="+eventCursor.getCount()); // If there are actual events in the current calendar, the count will exceed zero if(eventCursor.getCount()>0) { // Create a list of calendar events for the specific calendar List<CalendarEvent> eventList = new ArrayList<CalendarEvent>(); // Move to the first object eventCursor.moveToFirst(); // Create an object of CalendarEvent which contains the title, when the event begins and ends, // and if it is a full day event or not CalendarEvent ce = loadEvent(eventCursor); // Adds the first object to the list of events eventList.add(ce); System.out.println(ce.toString()); // While there are more events in the current calendar, move to the next instance while (eventCursor.moveToNext()) { // Adds the object to the list of events ce = loadEvent(eventCursor); eventList.add(ce); System.out.println(ce.toString()); } Collections.sort(eventList); eventMap.put(id, eventList); System.out.println(eventMap.keySet().size() + " " + eventMap.values()); } } } // Returns a new instance of the calendar object private static CalendarEvent loadEvent(Cursor csr) { return new CalendarEvent(csr.getString(0), new Date(csr.getLong(1)), new Date(csr.getLong(2)), !csr.getString(3).equals("0")); } // Creates the list of calendar ids and returns it in a set private static HashSet<String> getCalenderIds(Cursor cursor) { HashSet<String> calendarIds = new HashSet<String>(); try { // If there are more than 0 calendars, continue if(cursor.getCount() > 0) { // Loop to set the id for all of the calendars while (cursor.moveToNext()) { String _id = cursor.getString(0); String displayName = cursor.getString(1); Boolean selected = !cursor.getString(2).equals("0"); System.out.println("Id: " + _id + " Display Name: " + displayName + " Selected: " + selected); calendarIds.add(_id); } } } catch(AssertionError ex) { ex.printStackTrace(); } catch(Exception e) { e.printStackTrace(); } return calendarIds; } } |
Conclusion
The Calendar Service has proven to provide the help which I required in form of retrieving all the events from different calendars in a specific time range.
Furthermore, the service itself can be used for a variety of purposes and can easily be expanded for future purposes.
Future Work
I have personally created this service based on my own needs, but I would not hesitate improving it.
If you hereby are in need of specific features, please let me know and I will adapt the service as soon as possible.
Thanks for any feedback in advance.
References
As stated in the CalendarService, this repository has found inspiration from Akash Thakkar from Stackoverflow.
// David