One of the popular apps on Android device is the Calendar application. As one of the android app development philosophy is to make use of functionalities of other apps, it is expected by many developers that we can access the calendar data easily. However, the truth is NO!
Android doesn’t provide an official API for read/write Calendar data, probably because Android is going to change the calendar data format in future release.
The good news is there’re workarounds, more than one. This tutorial will list out those methods and provide an example at the end of the tutorial.
1. Google Calendar APIs
Google doesn’t provide Calendar API specifically for Android, but it does provide an Calendar API for more general use. The API supports .NET, Java and Python, so it is expected that it can be used in Android.
However, this method requires the app to establish a network connection through Internet (probably requires some kind of authentication), and then access the calendar data. As android already has Calendar app built in, it sounds dumb that we’ll need to connect to Internet, create a connection and access the data.
This approach is not explored in detail here. Interested readers could refer reference 2 for more details.
2. Android Calendar Private APIs
Android is open source, so it’s not difficult to find out that android actually has undocumented APIs for calendar (it’s just not public APIs).
This part will cover how to get list of calendars, how to read event, and how to add event.
2.0 Permission Declaration
In order to read calendar data, one needs to declare the “READ_CALENDAR” permission in AndroidManifest.xml file.
<uses-permission android:name="android.permission.READ_CALENDAR"></uses-permission>
For write to Calendar, there’s a another “WRITE_CALENDAR” permission.
<uses-permission android:name="android.permission.WRITE_CALENDAR"></uses-permission>
You can refer to the complete code at the end of the tutorial for exact position of the declaration.
2.1 List Calendars
One may have multiple calendars created in Calendar application. For me, I have the default calendar, a Singapore Holiday Calendar, and a third calendar from my other Gmail account.
The code to get a list of all calendars are as below,
class MyCalendar {
public String name;
public String id;
public MyCalendar(String _name, String _id) {
name = _name;
id = _id;
}
@Override
public String toString() {
return name;
}
}
private MyCalendar m_calendars[];
private void getCalendars() {
String[] l_projection = new String[]{"_id", "displayName"};
Uri l_calendars;
if (Build.VERSION.SDK_INT >= 8 ) {
l_calendars = Uri.parse("content://com.android.calendar/calendars");
} else {
l_calendars = Uri.parse("content://calendar/calendars");
}
Cursor l_managedCursor = this.managedQuery(l_calendars, l_projection, null, null, null); //all calendars
//Cursor l_managedCursor = this.managedQuery(l_calendars, l_projection, "selected=1", null, null); //active calendars
if (l_managedCursor.moveToFirst()) {
m_calendars = new MyCalendar[l_managedCursor.getCount()];
String l_calName;
String l_calId;
int l_cnt = 0;
int l_nameCol = l_managedCursor.getColumnIndex(l_projection[1]);
int l_idCol = l_managedCursor.getColumnIndex(l_projection[0]);
do {
l_calName = l_managedCursor.getString(l_nameCol);
l_calId = l_managedCursor.getString(l_idCol);
m_calendars[l_cnt] = new MyCalendar(l_calName, l_calId);
++l_cnt;
} while (l_managedCursor.moveToNext());
}
}
The code essentially queries the android calendar content provider and goes through the calendar list returned. The name and calendar id are stored in m_calendars[].
For android version less than 8, the uri for query calendars is content://calendar/*, while content://com.android.calendar/* is used for android version 8 and above.
2.2 Read Events
To read a list of Calendar events, one can create another query as illustrated below,
private void getLastThreeEvents() {
Uri l_eventUri;
if (Build.VERSION.SDK_INT >= 8 ) {
l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
l_eventUri = Uri.parse("content://calendar/events");
}
String[] l_projection = new String[]{"title", "dtstart", "dtend"};
Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, "calendar_id=" + m_selectedCalendarId, null, "dtstart DESC, dtend DESC");
//Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, null, null, null);
if (l_managedCursor.moveToFirst()) {
int l_cnt = 0;
String l_title;
String l_begin;
String l_end;
StringBuilder l_displayText = new StringBuilder();
int l_colTitle = l_managedCursor.getColumnIndex(l_projection[0]);
int l_colBegin = l_managedCursor.getColumnIndex(l_projection[1]);
int l_colEnd = l_managedCursor.getColumnIndex(l_projection[1]);
do {
l_title = l_managedCursor.getString(l_colTitle);
l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));
l_displayText.append(l_title + "\n" + l_begin + "\n" + l_end + "\n----------------\n");
++l_cnt;
} while (l_managedCursor.moveToNext() && l_cnt < 3);
m_text_event.setText(l_displayText.toString());
}
}
The method above get the last three events from the selected calendar. Note that m-selectedCalendarId variable and getDateTimeStr() method are defined by us. You can refer to code at the end of the tutorial for a complete picture.
2.3 Create an Event
Similarly, one can insert a new event into Calendar database.
/*add an event to calendar*/
private void addEvent() {
ContentValues l_event = new ContentValues();
l_event.put("calendar_id", m_selectedCalendarId);
l_event.put("title", "roman10 calendar tutorial test");
l_event.put("description", "This is a simple test for calendar api");
l_event.put("eventLocation", "@home");
l_event.put("dtstart", System.currentTimeMillis());
l_event.put("dtend", System.currentTimeMillis() + 1800*1000);
l_event.put("allDay", 0);
//status: 0~ tentative; 1~ confirmed; 2~ canceled
l_event.put("eventStatus", 1);
//0~ default; 1~ confidential; 2~ private; 3~ public
l_event.put("visibility", 0);
//0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
l_event.put("transparency", 0);
//0~ false; 1~ true
l_event.put("hasAlarm", 1);
Uri l_eventUri;
if (Build.VERSION.SDK_INT >= 8 ) {
l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
l_eventUri = Uri.parse("content://calendar/events");
}
Uri l_uri = this.getContentResolver().insert(l_eventUri, l_event);
Log.v("++++++test", l_uri.toString());
}
The code above simply create a ContentValues and insert it into the database URI.
3. Sending Intent to Calendar
This method doesn’t require the READ/WRITE_CALENDAR permission. It sends out an intent to calendar, and users will be redirected to Calendar app to create the event. Note that this is not a documented method either.
Below is a method that adds an event to Android Calendar.
/*add an event through intent, this doesn't require any permission
* just send intent to android calendar
*/
private void addEvent2() {
Intent l_intent = new Intent(Intent.ACTION_EDIT);
l_intent.setType("vnd.android.cursor.item/event");
//l_intent.putExtra("calendar_id", m_selectedCalendarId); //this doesn't work
l_intent.putExtra("title", "roman10 calendar tutorial test");
l_intent.putExtra("description", "This is a simple test for calendar api");
l_intent.putExtra("eventLocation", "@home");
l_intent.putExtra("beginTime", System.currentTimeMillis());
l_intent.putExtra("endTime", System.currentTimeMillis() + 1800*1000);
l_intent.putExtra("allDay", 0);
//status: 0~ tentative; 1~ confirmed; 2~ canceled
l_intent.putExtra("eventStatus", 1);
//0~ default; 1~ confidential; 2~ private; 3~ public
l_intent.putExtra("visibility", 0);
//0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
l_intent.putExtra("transparency", 0);
//0~ false; 1~ true
l_intent.putExtra("hasAlarm", 1);
try {
startActivity(l_intent);
} catch (Exception e) {
Toast.makeText(this.getApplicationContext(), "Sorry, no compatible calendar is found!", Toast.LENGTH_LONG).show();
}
}
This method is used in my android app, Advanced Phone Log.
4. A Complete and Runnable Example
The code snippet shown above are retrieved from an example. You can download the source code here, or find it at github.
Below are screenshots of the app.
Figure 1. Screenshots of Calendar Sample App
Reference:
1. Working with the Android Calendar:http://www.developer.com/ws/article.php/3850276/Working-with-the-Android-Calendar.htm
2. Google Calendar APIs and Tools:http://code.google.com/apis/calendar/data/2.0/developers_guide.html
No hay comentarios:
Publicar un comentario