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:
// 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:
<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:
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.
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