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