Google Apps Platform

Google Calendar API v2 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

You can use the Java client library to work with either public or private feeds. Public feeds are read-only and do not require any authentication. Private feeds require that you authenticate to the calendar service. When you work with private feeds, you should use OAuth for authentication. If you're unable to use OAuth for any reason, you can use ClientLogin or AuthSub until you can transition to OAuth. The calendar service also allows authentication to a read-only private feed using magic cookie authentication.

If you're not sure whether you can use OAuth with your application, see Getting Started with Account Authorization for an overview of various authentication methods.

OAuth

OAuth is an open-standard authentication protocol intended for web applications or installed applications. OAuth is similar to the secure and registered mode of AuthSub in that all data requests must be digitally signed and you must register your domain.

As with AuthSub authentication, first-time users of your application must authorize access to their Google data. Typically, your users see some text and a link or button directing them to authenticate (sign in) using their Google Account credentials. After they authenticate, users are directed to a URL where they can use your application to retrieve data from their Google data feed. This process is shown in the following diagram:

To use OAuth for your web based application, follow this sequence, each of which has a related code example you can use:

  1. Fetch a request token.
  2. Authorize the request token.
  3. Upgrade to an access token.
  4. Use the access token to interact with the service.

AuthSub for Web Applications

AuthSub is Google's proprietary authentication protocol for web-based applications. Use AuthSub in your web-based application when you can't use OAuth and you must get access to user data that is protected by a Google Account. To learn how AuthSub works and how to set it up for your project, see Working with AuthSub in the AuthSub for Web Applications guide.

When users first visit your application, they must authorize access to their Google data. In order to achieve this, your application must first obtain a single-use token, which grants your app access to user data without exposing their login credentials. Typically, your users see some text and a link or button directing them to authenticate (sign in) using their Google Account credentials. After they authenticate, users are directed to a URL where they can use your application to retrieve data from their Google data feed.

To use AuthSub in your web application, first request a single-use token:

Use the getRequestUrl() function provided by the Google Data Java client library to obtain a single-use token using AuthSub authentication.

import com.google.gdata.client.*;

String nextUrl = "http://www.example.com/welcome.jsp";
String scope = "https://www.google.com/calendar/feeds/";
boolean secure = false;  // set secure=true to request secure AuthSub tokens
boolean session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);

If you want to authenticate users on your Google Apps hosted domain:

import com.google.gdata.client.*;

String hostedDomain = "example.com";
String nextUrl = "http://www.example.com/welcome.jsp";
String scope = "https://www.google.com/calendar/feeds/";
boolean secure = false;  // set secure=true to request AuthSub tokens
boolean session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(hostedDomain, nextUrl, scope, secure, session);

The getRequestUrl() method takes several parameters. These parameters are described in detail in the AuthSubRequest documentation. Once you figure out how to retrieve the single-use token, you can read how to:

ClientLogin for Installed Applications

Use ClientLogin in your installed application when you can't use OAuth and you must get access to user data that is protected by a Google Account. When your application first runs, it prompts the user for username and password. For subsequent uses, it uses an authentication token to authenticate the user.

View instructions

To use ClientLogin, invoke the setUserCredentials() method of CalendarService object, which is inherited from GoogleService. Specify the email address and password of the user on whose behalf your client is making requests. For example:

CalendarService client = new CalendarService("yourCo-yourAppName-v1");
client.setUserCredentials("example@gmail.com", "pa$$word");

Tip: Once your application has successfully authenticated the user for the first time, store the auth token in your database to recall for later use. You should not prompt for the user's password on every run of your application. See Recalling an auth token for more information.

For more information on using ClientLogin in your Java applications, see Using ClientLogin with the Google Data API Client Libraries.

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.

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.

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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();

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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);
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.

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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.

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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").

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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.

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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().

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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.

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

Deleting events

To delete an existing item, use the following code:

updatedEntry.delete();

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

Note: If making multiple creations/updates/deletions at the same time, please consider using Batch Request as it increases performance.

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.addExtendedProperty(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.

Improving performance

Some special features are available to help you optimize your Calendar Data API requests.

Requesting a partial response (Experimental)

When you use the Java Client Library to work with the Calendar Data API, you are actually making underlying requests that transfer XML data using the Google Data Protocol. By default, requests that return data transfer the full representation of the target resource. Yet receiving full responses to requests can consume a lot of network and CPU resources, especially when you're making many requests. To reduce resource use, you can request that the server return only certain fields.

To request a partial response instead of a full response, use the CalendarQuery.setFields method. For more information, including the field-specification syntax, see the partial-response documentation.

For example, the following code retrieves attendee status for the user's next twenty upcoming events.

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

// Create a partial query to retrieve info for the next twenty events.
String eventFeedUrl = "https://www.google.com/calendar/feeds/jo@gmail.com/private/full";
CalendarQuery query = new CalendarQuery(new URL(eventFeedUrl));
// Selection criteria to fetch only the attendee status of the specified user for each retrieved event.
query.setFields("entry(@gd:etag,title,link[@rel='edit'],gd:who[@email='jo@gmail.com'])");
query.setMinimumStartTime(DateTime.now());
query.setMaxResults(20);

// Send query; using query results, print Jo's attendee status.
CalendarEventFeed partialEvents = myService.query(query, CalendarEventFeed.class);
for (CalendarEventEntry partialEvent : partialEvents.getEntries()) {
  // The participant list will contain exactly one attendee matching the
  // above partial query selection criteria.
  String myStatus = partialEvent.getParticipants().get(0).getAttendeeStatus();
  System.out.println(partialEvent.getTitle().getPlainText() + ": "
       + (myStatus != null ? myStatus : "no status"));
}

Note: The fields you specify with the CalendarQuery.setFields method are expressed in terms of the Google Data Protocol's AtomPub XML representation for the Calendar Data API. For more information about these fields, please see the schema reference documents: Calendar List Feed, Calendar Event Comments Feed, Calendar Events Feed.

For additional background on the Atom representation of the Calendar Data API, see the protocol and the reference documentation.

Making a partial update (Experimental)

When you change a field in a local copy of an entry, you can send the server just the updated fields, rather than sending the entire updated entry. For more information, see the partial update documentation.

The following code shows how to accept a calendar event by sending a partial update for an existing Calendar event. In this example we are updating the attendeeStatus for one of the events retrieved using partial response.

// Set status to accepted.
retrievedPartialEvent.getParticipants().get(0).setAttendeeStatus(Who.AttendeeStatus.EVENT_ACCEPTED);
// Specify which fields to update.
String fieldsToUpdate = "gd:who[@email='jo@gmail.com']";
// Send the changes.
URL editUrl = new URL(retrievedPartialEvent.getEditLink().getHref());
CalendarEventEntry updatedEvent = myService.patch(editUrl, fieldsToUpdate, retrievedPartialEvent);

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.

To compile the example into your own code, you'll need to add the following import statement:

import com.google.gdata.data.batch.*;
// 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.

Authentication required

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

Signing you in...

Google Developers needs your permission to do that.