Google Apps Platform

Google Calendar API v1 Developer's Guide: Java

This API is a subject to the Deprecation Policy and will be deprecated on November 17, 2014. Please use APIv3 instead.

Google Calendar allows client applications to view and update calendar events in the form of Google Data API feeds. Your client application can use the Google Calendar Data API to create new events, edit or delete existing events, and query for events that match particular criteria.

There are many possible uses for the Calendar Data API. For example, you can create a web front end for your group's calendar that uses Google Calendar as a back end. Or you can generate a public calendar for Google Calendar to display, based on your organization's event database. Or you can search relevant calendars to display a list of upcoming events on those calendars.

This document provides detailed examples for using the Java Client Library to work with the Google Calendar service. For help setting up the client library, see the Getting Started Guide. You will find examples of adding events, updating events, deleting events and querying events. If you're interested in understanding more about the underlying protocol used by the Java Client Library to interact with the Calendar Data API, please see the protocol tab.

Contents

Audience

This document is intended for programmers who want to write client applications using the Google Data API Java client library that can interact with Google Calendar.

Getting started

For help setting up the client library, see the Getting Started Guide. To use the Java client library, you must be running Java 1.5. After downloading the client library, you'll find the classes you need to get started in the java/lib/gdata-calendar-1.0.jar and java/lib/gdataclient-1.0.jar jar files.

A full working copy of this sample is available in the distribution, under the directory gdata/java/sample/calendar. Build and execution instructions are included in the same directory, in the file README.txt. To run the sample, you'll need to modify the following values in gdata/java/build.properties:

  • sample.credentials.username is the username you use to log in to Google Calendar.
  • sample.credentials.password is the password you use to log in to Google Calendar.
  • sample.calendar.feedUrl should have the value https://www.google.com/calendar/feeds/default/private/full if you want the client to use your primary calendar. If you'd like to use another calendar, you can find the calendar's address in the Google Calendar UI. Click the arrow next to the calendar's name in the left sidebar, and choose Calendar settings from the drop-down menu. Then copy and paste the "XML" URL for the Calendar Address seen on the "Calendar Details" tab. Please replace the suffix /public/basic with /private/full in the URL, as the sample will be authenticating using the provided credentials.
  • sample.calendar.aclFeedUrl value is typically https://www.google.com/calendar/feeds/default/acl/full, when working with your primary calendar. If you're using another calendar, replace /private with /acl in the feed URL above.

The sample performs a number of operations on the provided calendar to demonstrate the use of the Calendar Data API. Please see the main method of the code for more details as to which operations are performed.

To compile the examples in this document into your own code, you'll need to use the following import statements:

import com.google.gdata.client.*;
import com.google.gdata.client.calendar.*;
import com.google.gdata.data.*;
import com.google.gdata.data.acl.*;
import com.google.gdata.data.calendar.*;
import com.google.gdata.data.extensions.*;
import com.google.gdata.util.*;
import java.net.URL;

The CalendarService class represents a client connection (with authentication) to a service. The general procedure for sending a query to a service using the client library consists of the following steps:

  1. Obtain or construct the appropriate URL.
  2. If you're sending data to a service (for example, if you're inserting a new entry), then transform the raw data into objects using the client library classes. (This step doesn't apply if you're just requesting a feed, as we're doing in this example.)
  3. Create a new CalendarService instance, setting your application's name (in the form companyName-applicationName-versionID).
  4. Set the appropriate credentials.
  5. Call a method to send the request and receive any results.

Authenticating to the Calendar service

The Java client library can be used to work with either public or private feeds. Public feeds are read-only, but do not require any authentication. Private feeds require that you authenticate to the calendar servers. This can be done via ClientLogin username/password authentication or AuthSub proxy authentication. The calendar service also allows authentication to a read-only private feed using magic cookie authentication.

Please see the authentication documentation for more information on AuthSub and ClientLogin.

AuthSub proxy authentication

To acquire an AuthSub token for a given user and a given service, your application must redirect the user to the AuthSubRequest URL, which prompts them to log into their Google account. (For more information on the AuthSubRequest URL, see the AuthSub documentation.)

To construct the AuthSubRequest URL for your application, make a Java client library call as follows:

String requestUrl =
  AuthSubUtil.getRequestUrl("http://www.example.com/RetrieveToken",
                            "https://www.google.com/calendar/feeds/",
                            false,
                            true);

The getRequestUrl method takes several parameters (corresponding to the query parameters used by the AuthSubRequest handler): the "next" URL (which is the URL that Google will redirect to after the user logs into their account and grants access); the scope (as determined in the previous section); and two Booleans, one to indicate whether the token will be used in registered mode or not, and one to indicate whether the token will later be exchanged for a session token or not. The above example shows a call in unregistered mode (the first Boolean is false), for a token that will be exchanged for a session token later (the second Boolean is true); adjust the Booleans appropriately for your application.

After constructing the "next" URL, your server-side application can use it in a variety of ways to send the user to the AuthSubRequest handler. The most common approach is to display a page that tells the user that they need to follow a link to authorize your application to access your Google account; then attach the request URL to the link. For example, you could display the following string on a page:

String suggestAuthorization = "<p>MyApp needs access to your
  Google Calendar account to read your Calendar feed. To authorize
  MyApp to access your account, <a href=\"" + requestUrl + "\">log in
  to your account</a>.</p>";

The user follows the link to the AuthSub page at Google, and logs in. The AuthSub system then redirects the user back to your application, using the "next" URL you provided.

When Google redirects back to your application, the token is appended to the "next" URL as a query parameter. So in the case of the above "next" URL, after the user logs in, Google redirects to a URL like http://www.example.com/RetrieveToken?token=DQAADKEDE.

The user's browser is redirected to that URL. The servlet handling that URL should then examine the query parameters in the requested URL to retrieve the token set by Google. For example, the servlet can retrieve the token from the URL by using the convenience function getTokenFromReply from the Java client library:

String onetimeUseToken = AuthSubUtil.getTokenFromReply(httpServletRequest.getQueryString());

If your application set an authentication cookie in the user's browser before sending them to the AuthSub system, then when Google redirects back to the "next" URL, your application can read the authentication cookie to recognize which user has arrived at that URL. You can use such a cookie to associate a user ID in your application with the AuthSub token retrieved from Google.

The token you retrieve with getTokenFromReply is always a one-time use token. You can exchange this token for a session token using the AuthSubSessionToken URL, as described in the AuthSub documentation. Your application can make this exchange using the Java client library as follows:

String sessionToken = AuthSubUtil.exchangeForSessionToken(onetimeUseToken,
                                                          null);

You pass your one-time use token to the exchangeForSessionToken method, along with either null (for unregistered mode) or a private key (for registered mode), and the AuthSub interface returns a session token. For more information about registered applications and private keys, refer to the AuthSub documentation.

You can use the session token to authenticate requests to the server by placing the token in the Authorization header, as described in the AuthSub documentation. To tell the Java client library to automatically send the Authorization header (containing the session token) with each request, you call the CalendarService object's setAuthSubToken method:

CalendarService.setAuthSubToken(sessionToken, null);

Again, if you're using registered mode, then you provide your private key instead of null.

After you've called setAuthSubToken, you can use the standard Google Data API client library calls to interact with the service, without having to think about the token. For details, see the client library documentation and the Data API documentation for the service you're interacting with.

If you want to test that your client and the server agree on the token's parameters, you can pass the token to the getTokenInfo method, which returns a set of name-value pairs containing information about the token. For example:

Map<String, String> info = AuthSubUtil.getTokenInfo(sessionToken, null);  

AuthSub session tokens don't expire; your client can store the session token for as long as needed.

Therefore, when your client is done using the session token, it can revoke the token using the AuthSubRevokeToken handler, as described in the AuthSub documentation.

For example, if you want to manage tokens in a traditional session-like way, then your client can get a token at the beginning of a user's session and revoke it at the end of the user's session.

To revoke a token using the Java client library, call revokeToken. Include your private key for registered mode, or null otherwise. For example:

AuthSubUtil.revokeToken(sessionToken, null);

ClientLogin username/password authentication

To use ClientLogin (also called "Authentication for Installed Applications"), invoke the setUserCredentials method of CalendarService, specifying the ID and password of the user on whose behalf your client is sending the query. For example:

CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo@gmail.com", "mypassword");

For more information about authentication systems, see the Google Account Authentication documentation.

Magic cookie authentication

The simplest feed URL to use is that of the calendar's read-only so-called "magic cookie" private feed, because that URL doesn't require authentication. The usual procedure for determining that URL involves using a JavaScript-enabled GUI browser to get the URL manually. If you can't or don't want to use such a browser, then you can instead interact with Calendar using one of the other feed URLs, which require authentication, but which you can construct without using a browser. Those URLs (and information on how to use authentication) are covered in later examples, but even if you aren't going to use the "magic cookie" URL, you should read through the first couple of examples to learn the basics of sending Calendar requests.

To find your calendar's "magic cookie" feed URL:

  1. In the list of calendars on the left side of the page, find the calendar you want to interact with. You can create a new calendar for this purpose if you want to.
  2. Click the arrow button to the right of the calendar. Select "Calendar settings" from the drop-down menu. The Calendar Details page appears.
  3. Scroll down to the Private Address section. There are two buttons; select the XML button. The feed URL appears.
  4. Copy the URL. This is the URL of your calendar's read-only "magic cookie" private feed; it includes a special coded string that lets you read the private feed without having to do authentication. This is the URL you'll use to request a feed from Calendar, so you won't have to do authentication just to view the feed.

The feed URL has the following form:

https://www.google.com/calendar/feeds/userID/private-magicCookie/basic

You can modify this URL in the following ways:

  • If you want a private feed that requires authentication, convert the "private-{magic-cookie}" part of this path to just "private".
  • If you want the "full" calendar project, change the last component from "basic" to "full" in the URL. Using "basic" returns a basic Atom feed without any extension elements. Using "full" returns a feed that includes all event properties, but comments aren't included inline. Instead, they're specified (in the <gd:feedLink> element) as a link to a separate comment feed.

The "basic" form of the feed holds event information that is formatted for reading, more suited to human consumption of the feed. The "full" form of the feed holds structured events that are represented as "Kinds", so they are more suited to computer processing.

If you're looking at settings for the user's main calendar, then userID is the user's email address. If you're looking at settings for another calendar, then userID is a longer and more complicated email address. In either case, magicCookie is a special code that lets you read the private feed without having to do authentication. Here's an example of a feed URL:

https://www.google.com/calendar/feeds/jo@gmail.com/private-08ce2fac8efa42f2a0d04eceb7d68cc9/full

Under some circumstances, you may want to generate a new "magic cookie" URL. (Note that if someone else gets access to that URL, they can view your calendar without authentication.) To do that, click the "Reset Private URLs" link in the Calendar Details page.

Retrieving calendar lists

The Calendar Data API provides several ways to access the list of calendars that appear in the Google Calendar web application. There are three types of calendars in this list: primary, secondary, and imported calendars. A primary calendar is created for a user when they sign up for a Google Calendar account. All other calendars created by that user are called secondary calendars. Imported calendars are calendars that a user subscribes to that someone else has created.

Retrieving all calendars

You can get a list of a user's calendars by sending an authenticated GET request to the allcalendars feed URL:

https://www.google.com/calendar/feeds/default/allcalendars/full

The result is a feed that includes all primary, secondary, and imported calendars.

Note: This feed is accessible only using an authentication token, so you cannot use a magic cookie URL to access the feed. For information on authentication, see the earlier Authenticating to the Calendar service section.

To request this feed using the Java client library, first instantiate a new CalendarService object and authenticate the user. Then use the getFeed method to retrieve a CalendarFeed object that contains entries for all of the user's calendars.

// Create a CalenderService and authenticate
CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo@gmail.com", "mypassword");

// Send the request and print the response
URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/allcalendars/full");
CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);
System.out.println("Your calendars:");
System.out.println();
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
  CalendarEntry entry = resultFeed.getEntries().get(i);
  System.out.println("\t" + entry.getTitle().getPlainText());
}

Retrieving only calendars that a user owns

There is also an owncalendars feed that you can query to retrieve the list of calendars that the authenticated user has owner access to. The owncalendars feed is located at:

https://www.google.com/calendar/feeds/default/owncalendars/full

Querying this feed will return a list of calendars that includes the user's primary and secondary calendars, as well as any imported calendars for which the user has been granted ownership. The feed can be accessed by replacing the URL in the previous example:

// Create a CalenderService and authenticate
CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo@gmail.com", "mypassword");

// Send the request and print the response
URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/owncalendars/full");
CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);
System.out.println("Calendars you own:");
System.out.println();
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
  CalendarEntry entry = resultFeed.getEntries().get(i);
  System.out.println("\t" + entry.getTitle().getPlainText());
}

Managing Calendars

The owncalendars feed can also be used to create, update, and delete calendars. Calendars created through the owncalendars feed will be secondary calendars.

Creating new calendars

To create a new calendar, first instantiate a CalendarEntry object and set the appropriate values. Then call the CalendarService.insert method, specifying the owncalendars feed. The following example uses an authenticated CalendarService object called myService:

// Create the calendar
CalendarEntry calendar = new CalendarEntry();
calendar.setTitle(new PlainTextConstruct("Little League Schedule"));
calendar.setSummary(new PlainTextConstruct("This calendar contains the practice schedule and game times."));
calendar.setTimeZone(new TimeZoneProperty("America/Los_Angeles"));
calendar.setHidden(HiddenProperty.FALSE);
calendar.setColor(new ColorProperty("#2952A3"));
calendar.addLocation(new Where("","","Oakland"));

// Insert the calendar
URL postUrl = new URL("https://www.google.com/calendar/feeds/default/owncalendars/full");
CalendarEntry returnedCalendar = myService.insert(postUrl, calendar);

Note: The <atom:id> field of the calendar entry should be null because the Google Calendar server will create an id for the entry when it process the request.

Updating existing calendars

You can update most information about a user's calendar via the owncalendars feed. The following example updates the title and color of the first calendar retrieved from the owncalendars feed.

URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/owncalendars/full");
CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);
CalendarEntry calendar = resultFeed.getEntries().get(0);
calendar.setTitle(new PlainTextConstruct("New title"));
calendar.setColor(new ColorProperty("#A32929"));
calendar.setSelected(SelectedProperty.TRUE);
CalendarEntry returnedCalendar = calendar.update();

Deleting calendars

To delete a calendar, simply call the delete method. The following example attempts to delete all the calendars that are returned in the feed:

URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/owncalendars/full");
CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);
CalendarEntry calendar = resultFeed.getEntries().get(0);
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
  CalendarEntry entry = resultFeed.getEntries().get(i);
  System.out.println("Deleting calendar: " + entry.getTitle().getPlainText());
  try {
    entry.delete();
  } catch (InvalidEntryException e) {
    System.out.println("\tUnable to delete primary calendar");
  }
}

Note: You can't delete a user's primary calendar, i.e. the calendar with the user's email address in the ID. If you try to delete a primary calendar you will get an InvalidEntryException.

Managing subscriptions to calendars

The allcalendars feed can be used to modify the list of imported calendars that a user has subscribed to. Calendars inserted via the allcalendars feed will be added as imported calendars.

Adding new subscriptions

To subscribe to an existing calendar, you first need to find the calendar's ID. The calendar ID is available on the calendar settings page, next to the Calendar Address buttons. If you're subscribing to a user's primary calendar, the id will just be the user's email address.

Once you have the calendar's ID, you can instantiate a CalendarEntry object and use the setId method to specify the calendar to subscribe to. Then call the CalendarService.insert method, specifying the allcalendars feed. The following example uses an authenticated CalendarService object called myService to subscribe to the Google Doodles calendar:

CalendarEntry calendar = new CalendarEntry();
calendar.setId("c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com");
URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/allcalendars/full");
CalendarEntry returnedCalendar = myService.insert(feedUrl, calendar);

This invocation of insert will have different results based on the current state of the calendar. If the subscription doesn't exist, then the calendar is added to the user's list of imported calendars. If the user has already subscribed to the calendar, then the server will return a 409 Conflict. If the calendar inserted is currently hidden, it will become visible.

Updating calendar subscriptions

You can update the following personalization settings of a calendar using the allcalendars feed:

  • color - the color of the calendar in the UI.
  • hidden - whether or not the calendar is shown in the UI.
  • selected - whether or not the calendar is selected in the UI.

The personalization settings can be modified with the allcalendars feed even if the user doesn't own the calendar. However, the title and summary of the calendar can only be updated by an owner of the calendar using the owncalendars feed. The following example turns all the calendars in the feed green:

URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/allcalendars/full");
CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
  CalendarEntry calendar = resultFeed.getEntries().get(i);
  calendar.setColor(new ColorProperty("#0D7813"));
  CalendarEntry returnedCalendar = calendar.update();
}

Deleting subscriptions

To remove an imported calendar, retrieve the calendar from the allcalendars feed and call the delete method. The following example removes the subscription to the Google Doodles calendar that was added in a previous example:

String doodleCalendarUrl = "https://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com";
CalendarEntry doodleCalendar = myService.getEntry(new URL(doodleCalendarUrl), CalendarEntry.class);
doodleCalendar.delete();
    

Retrieving events

Retrieving events without query parameters

To request a Calendar feed using the Java client library, for a user with email address "jo@gmail.com" and password "mypassword", use the following code:

// Set up the URL and the object that will handle the connection:
URL feedUrl = new URL("https://www.google.com/calendar/feeds/jo@gmail.com/private/full");
CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo@gmail.com", "mypassword");

// Send the request and receive the response:
CalendarEventFeed myFeed = myService.getFeed(feedUrl, CalendarEventFeed.class);

To request an entire feed, you call the getFeed method, which takes a URL and returns the entire feed found at that URL. We'll show how to send more specific queries later in this document.

Like other methods of the CalendarService class, getFeed handles authentication and redirects as necessary.

Retrieving events for a specified date range

To view events on your calendar that overlap a particular date range, use the following Java code. You'll have to replace the credentials in this example with the user's email address and password.

URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/private/full");

CalendarQuery myQuery = new CalendarQuery(feedUrl);
myQuery.setMinimumStartTime(DateTime.parseDateTime("2006-03-16T00:00:00"));
myQuery.setMaximumStartTime(DateTime.parseDateTime("2006-03-24T23:59:59")); CalendarService myService = new CalendarService("exampleCo-exampleApp-1"); myService.setUserCredentials("jo@gmail.com", "mypassword"); // Send the request and receive the response: CalendarEventFeed resultFeed = myService.query(myQuery, Feed.class);

The above code creates a new CalendarQuery, which is a subclass of Query (the class corresponding to a standard Data API query) that adds getters and setters for the start-min and start-max Calendar-specific query parameters. Then it sets the minimum and maximum start times; then it creates a CalendarService, uses the setUserCredentials method to set the username and password, and calls the query method to send the query and receive the response.

Retrieving events matching a full text query

To retrieve the first match in a full-text search, use the following code:

Query myQuery = new Query(feedUrl);
myQuery.setFullTextQuery("Tennis");
CalendarEventFeed myResultsFeed = myService.query(myQuery,
    CalendarEventFeed.class);
if (myResultsFeed.getEntries().size() > 0) {
  CalendarEventEntry firstMatchEntry = (CalendarEventEntry)
      myResultsFeed.getEntries().get(0);
  String myEntryTitle = firstMatchEntry.getTitle().getPlainText();
}

This example starts by constructing a Query object, which consists mostly of a URL plus associated query parameters. Each of the standard Data API query parameters has a setter method. You can also set custom query parameters for a particular service, using the addCustomParameter method.

After constructing the Query, we pass it to the service's query method, which returns a feed containing the query results. An alternative approach would be to construct a URL yourself (by appending query parameters to the feed URL) and then call the getFeed method, but the query method provides a useful layer of abstraction so that you don't have to construct the URL yourself.

The feed's getEntries method returns a list of the entries in the feed; getEntries().size returns the number of entries in the feed.

In this case, if the query returned any results, we assign the first matching result to an CalendarEventEntry object. Then we use the CalendarEventEntry class's getTitle().getPlainText method to retrieve the entry's title and convert it to text.

The above code is equivalent to sending GET https://www.google.com/calendar/feeds/jo@gmail.com/private/full?q=Tennis to Calendar.

Creating events

The Calendar Data API allows you to create two types of events: single-occurrence events and recurring events, which are set up to repeat on a predetermined schedule.

Creating single-occurrence events

To insert a single-occurrence event into a Calendar feed, you might use the following code:

URL postUrl =
  new URL("https://www.google.com/calendar/feeds/jo@gmail.com/private/full");
CalendarEventEntry myEntry = new CalendarEventEntry();

myEntry.setTitle(new PlainTextConstruct("Tennis with Beth"));
myEntry.setContent(new PlainTextConstruct("Meet for a quick lesson."));

DateTime startTime = DateTime.parseDateTime("2006-04-17T15:00:00-08:00");
DateTime endTime = DateTime.parseDateTime("2006-04-17T17:00:00-08:00");
When eventTimes = new When();
eventTimes.setStartTime(startTime);
eventTimes.setEndTime(endTime);
myEntry.addTime(eventTimes);

// Send the request and receive the response:
CalendarEventEntry insertedEntry = myService.insert(postUrl, myEntry);

After setting the URL, we construct a CalendarEventEntry object; CalendarEventEntry is derived from the abstract base class BaseEntry, which is also the parent class for the Entry class, which represents an <atom:entry> element.

The CalendarEventEntry class represents the Google Calendar implementation of the Google Data API Event kind; for more information, see the Kinds document. For services other than Calendar, you might assign the returned entry to an Entry object rather than a CalendarEventEntry object.

The entry title is a TextConstruct, a class that holds text in various forms (plain text, HTML, or XHTML). The entry content is represented by a Content object, a class that can hold either plain text or other forms of content, including XML and binary data. (But the setContent method can also accept a TextConstruct.)

We're using the same CalendarService object that we created in the previous example. In this case, the method to call is insert, which sends an item to the specified insertion URL.

The service returns the newly created entry, which may contain additional server-generated elements, such as an edit URL for the entry.

HTTP status codes indicating failure are thrown as exceptions.

The above code is equivalent to sending POST https://www.google.com/calendar/feeds/jo@gmail.com/private/full (with proper authentication) and providing an entry in the form of an Event kind.

Creating quick add events

To create an event using Google Calendar's quick add feature, set the entry's content to the quick add string you'd like to use. Then call setQuickAdd on the new entry, as follows:

CalendarEventEntry myEntry = new CalendarEventEntry();
myEntry.setContent(new PlainTextConstruct("Tennis with John April 11 3pm-3:30pm"));
myEntry.setQuickAdd(true);

// Send the request and receive the response:
CalendarEventEntry insertedEntry = myService.insert(postUrl, myEntry);

Notice that it's not necessary to call setTitle when creating an event with quick add; the title is parsed automatically (in this case, "Tennis with John").

Creating Calendar Event Gadgets

You can also insert Calendar Event Gadgets events using the Java Client Library. Calendar Event Gadgets, formerly called web content, can contain images, HTML pages, or gadgets.

To create a simple Calendar Event Gadget that displays and image first instantiate a new WebContent object and set its properties, as follows:

WebContent wc = new WebContent();

wc.setTitle("World Cup");
wc.setType("image/gif");
wc.setUrl("http://www.google.com/logos/worldcup06.gif");
wc.setIcon("http://www.google.com/calendar/images/google-holiday.gif");
wc.setWidth("276");
wc.setHeight("120");

This code sets up a WebContent object to display the World Cup doodle (dimensions 276x120, and located at http://www.google.com/logos/worldcup06.gif). The icon at http://www.google.com/calendar/images/google-holiday.gif will be used to display the Calendar Event Gadget in the Calendar user interface before it is clicked.

To create a Calendar Event Gadget that displays a gadget, create a WebContent object again, but this time the type should be application/x-google-gadgets+xml. You'll also need to get the gadget's URL from the iGoogle Directory. This example configures a Calendar Event Gadget to display the DateTime gadget and specifies the appropriate user preferences.

WebContent wc = new WebContent();

wc.setTitle("DateTime Gadget (a classic!)");
wc.setType("application/x-google-gadgets+xml");
wc.setUrl("http://google.com/ig/modules/datetime.xml");
wc.setIcon("http://www.google.com/calendar/images/google-holiday.gif");
wc.setWidth("300");
wc.setHeight("136");

Map<String, String> prefs = new HashMap<String,String>();
prefs.put("color", "green");
wc.setGadgetPrefs(prefs);

Once you've created the WebContent object, call setWebContent to associate the WebContent object with your new entry, and insert the event as follows:

myEntry.setWebContent(wc);
CalendarEventEntry insertedEntry = myService.insert(postUrl, myEntry);

It's also possible to add web content to an existing event, as follows:

entry.setWebContent(wc);
entry.update();

This inserts the Calendar Event Gadget on the current date. Please see the section on Creating single-occurrence events for information on how to set the start_time property to choose the date when the Calendar Event Gadget should appear on the calendar.

Note: For more information on Calendar Event Gadgets, check out the documentation here.

Creating recurring events

To create a recurring event, use code similar to the following:

String recurData = "DTSTART;VALUE=DATE:20070501\r\n"
        + "DTEND;VALUE=DATE:20070502\r\n"
        + "RRULE:FREQ=WEEKLY;BYDAY=Tu;UNTIL=20070904\r\n";

CalendarEventEntry myEntry = new CalendarEventEntry();
Recurrence recur = new Recurrence();
recur.setValue(recurData);
myEntry.setRecurrence(recur);

In this example, we first create a string containing an iCalendar (RFC 2445) specification of the desired event recurrence. Here, the event occurs first on 2007/05/01 and repeats weekly on Tuesdays until 2007/09/04. Next, a new Recurrence object is constructed and its value is set to the recurrence string. Finally, a new CalendarEventEntry is created and the recurrence added with setRecurrence().

Updating events

To update an existing item, use the following code. In this example, we're changing the previously retrieved entry's title from its old text ("Tennis with Beth") to "Important meeting."

retrievedEntry.setTitle(new PlainTextConstruct("Important meeting"));
URL editUrl = new URL(retrievedEntry.getEditLink().getHref());
CalendarEventEntry updatedEntry = (CalendarEventEntry)myService.update(editUrl, myEntry);

First we set a new title for the entry we fetched earlier. Then we get the edit URL for the entry, using the getEditLink method. Then we call the service's update method to send the updated entry.

The service returns the updated entry, including a new URL for this entry's new version. (For more information on entry versions, see the Optimistic concurrency section of the Google Data API Protocol reference.)

The above code is roughly equivalent to sending PUT https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID to the service, along with the new entry (in Atom format) to replace the original entry.

Deleting events

To delete an existing item, use the following code:

URL deleteUrl = new URL(updatedEntry.getEditLink().getHref());
myService.delete(deleteUrl);

The URL to use for deletion is the same as the edit URL, so this example is very similar to the previous one, except of course that we're calling the delete method instead of update.

The above code is roughly equivalent to sending DELETE https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID to the service.

Performing multiple operations with a batch request

If you're performing a lot of operations, the time it takes to send and and receive all those HTTP messages can really add up, making your app slow and unresponsive. With batch requests you can have the server perform multiple operations with a single HTTP request. The basic idea is that you create a CalendarEventFeed object and add an entry for each operation you want to perform. The following code snippet builds and submits a batch request that contains four operations, one each for creating, querying, updating, and deleting an event, but you can use any combination of operations that you want. The snippet also shows how to check the batch response to make sure the operations were successful. Note that the service object is an authenticated instance of the CalendarService class.

// Get some events to operate on.
URL defaultEventFeedUrl = new URL("https://www.google.com/calendar/feeds/default/private/full");
CalendarEventFeed feed = service.getFeed(defaultEventFeedUrl, CalendarEventFeed.class);

// Create an batch entry to insert a new event.
CalendarEventEntry toInsert = new CalendarEventEntry();
toInsert.setTitle(new PlainTextConstruct("first batch event"));
BatchUtils.setBatchId(toInsert, "1");
BatchUtils.setBatchOperationType(toInsert, BatchOperationType.INSERT);

// Create an batch entry to query an event.
CalendarEventEntry toQuery = feed.getEntries().get(0);
BatchUtils.setBatchId(toQuery, "2");
BatchUtils.setBatchOperationType(toQuery, BatchOperationType.QUERY);

// Create an batch entry to update an existing event.
CalendarEventEntry toUpdate = feed.getEntries().get(1);
toUpdate.setTitle(new PlainTextConstruct("updated via batch"));
BatchUtils.setBatchId(toUpdate, "3");
BatchUtils.setBatchOperationType(toUpdate, BatchOperationType.UPDATE);

// Create an batch entry to delete an existing event.
CalendarEventEntry toDelete = feed.getEntries().get(2);
BatchUtils.setBatchId(toDelete, "4");
BatchUtils.setBatchOperationType(toDelete, BatchOperationType.DELETE);

// Add the entries to a new feed.
CalendarEventFeed batchRequest = new CalendarEventFeed();
batchRequest.getEntries().add(toInsert);
batchRequest.getEntries().add(toQuery);
batchRequest.getEntries().add(toUpdate);
batchRequest.getEntries().add(toDelete);

// Get the batch link URL and send the batch request there.
Link batchLink = feed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
CalendarEventFeed batchResponse = service.batch(new URL(batchLink.getHref()), batchRequest);

// Ensure that all the operations were successful.
boolean isSuccess = true;
for (CalendarEventEntry entry : batchResponse.getEntries()) {
  String batchId = BatchUtils.getBatchId(entry);
  if (!BatchUtils.isSuccess(entry)) {
    isSuccess = false;
    BatchStatus status = BatchUtils.getBatchStatus(entry);
    System.out.println("\n" + batchId + " failed (" + status.getReason() + ") " + status.getContent());
  }
}
if (isSuccess) {
  System.out.println("Successfully deleted all events via batch request.");
}

When working with batch requests, the size of the request must be under a megabyte and it's best to limit batches to 50-100 operations at a time. You can find more information about batch operations in the Google Data API Batch Processing documentation.

Sharing calendars

This section describes how to retrieve and modify Calendar access control lists (ACLs) with the Google Data API Java client library. An access control list identifies the set of users with whom a calendar is shared, and the access permissions of each user (read-only access, full access, etc.) For more information, see the ACL topic of the Protocol section.

Retrieving access control lists

To retrieve and print the access control lists of all of your calendars, use the following code. Here service is an authenticated CalendarService object.

CalendarFeed calendarFeed =
    service.getFeed(new URL("https://www.google.com/calendar/feeds/default"), CalendarFeed.class);

for (CalendarEntry calEntry : calendarFeed.getEntries()) {
  System.out.println("Calendar: " + calEntry.getTitle().getPlainText());
  Link link = calEntry.getLink(AclNamespace.LINK_REL_ACCESS_CONTROL_LIST,
      Link.Type.ATOM);

  // For each calendar, retrieve its ACL feed.
  AclFeed aclFeed = service.getFeed(new URL(link.getHref()), AclFeed.class);
  for(AclEntry aclEntry : aclFeed.getEntries()) {
    System.out.println("\t\tScope: Type=" + aclEntry.getScope().getType() +
        " (" + aclEntry.getScope().getValue() + ")");
    System.out.println("\t\tRole: " + aclEntry.getRole().getValue());
  }
}

After accessing the "meta-feed" to retrieve a list of all calendars, we extract the ACL link for each calendar and retrieve that feed. These links have the form https://www.google.com/calendar/feeds/<userId>/acl/full.

We then print each entry in the feed. An AclEntry consists of a scope, which defines a user with access to this calendar, and a role, which defines how much access he or she has. Valid roles are:

Note: Google Data ACLs define scopes that encompass more than one user, though the examples here only use AclScope.Type.USER for simplicity. Specifically, AclScope.Type.DOMAIN (available only in Google Apps) indicates that an access rule applies to all users with email addresses in the domain, while AclScope.Type.DEFAULT specifies an access rule that applies to all users. For more information, see the GAcl namespace element reference.

Adding a user to an access control list

To add a user to a calendar's access control list, you might do the following:

AclEntry entry = new AclEntry();
entry.setScope(new AclScope(AclScope.Type.USER, "jdoe@gmail.com"));
entry.setRole(CalendarAclRole.READ);

URL aclUrl =
  new URL("https://www.google.com/calendar/feeds/jo@gmail.com/acl/full");

AclEntry insertedEntry = service.insert(aclUrl, entry);

This code allows jdoe@gmail.com to have read-only access to jo@gmail.com's calendar. Note that if an attempt is made to add an entry with a scope whose type and value match another entry already in the access control list, the operation will fail with error code 409 (Conflict).

Updating a user's role in an ACL

In order to change a user's access level to a calendar, update the AclEntry with the following code:

entry.setRole(CalendarAclRole.OWNER);
AclEntry updatedEntry = entry.update();

This code changes entry to a rule indicating that the user defined in its scope has full (owner) access privileges.

Note: It is not possible to modify the scope of an AclEntry when updating it; only the role can be modified. An attempt to update the scope will result in a 403 (Forbidden) error.

Removing a user from an access control list

To remove a user from a calendar's access control list, do the following:

entry.delete();

Here entry is an AclEntry that was already defined as a variable or retrieved from an AclFeed. Executing this code will cause the user defined in entry's scope to lose access to this calendar.

Additional operations

This section describes other Calendar operations you can perform with the Google Data API Java client library.

Extended properties

You can add extended properties (arbitrary name-value pairs) to Calendar events. These can be used to store application-specific IDs or other small amounts of information your application needs when interacting with a Google Calendar. The name of a property can contain up to 47 characters, and the value can contain up to 1024 characters. Extended properties are only accessible through the API – they do not appear in the Calendar user interface.

In this example, we are adding an extended property id with value 1234 to the Calendar entry myEntry. It is recommended that you specify the complete schema URL to avoid namespace collisions with other applications that use the same property name:

ExtendedProperty property = new ExtendedProperty();
property.setName("http://www.example.com/schemas/2005#mycal.id");
property.setValue("1234");

myEntry.addExtension(property);

Note: Extended properties are not indexed so you can't query based on their keys or values.

Reminders and Notifications

To set a reminder for a calendar event, you can do the following:

int reminderMinutes = 15;
Method methodType = Method.EMAIL;

Reminder reminder = new Reminder();
reminder.setMinutes(reminderMinutes);
reminder.setMethod(methodType);

entry.getReminder().add(reminder);
entry.update();

This code sets a 15-minute email reminder for the event myEntry. You can include up to five reminders per event. The available methods are email, alert (a popup in the browser), sms (a text message), or none. By default every event created through the Google Calendar interface is associated with a SMS reminder, even if SMS notifications are not enabled in your Google Calendar account setting.

For an event to inherit the default reminder setting of your Google Calendar account, add a reminder with the method set to Method.ALL.

If you want to ensure that no reminders are sent, add a reminder with the method set to Method.NONE.

Note: The value of the minutes attribute must correspond to one of the reminder time increments available in the Google Calendar web application.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.