7

我正在尝试使用 Java Google Calendar api 连接到日历。Java 应用程序使用服务帐户。

我有以下代码:

   java.io.File licenseFile = new java.io.File("39790cb51b361f51cab6940d165c6cda4dc60177-privatekey.p12");

   GoogleCredential credential = new GoogleCredential.Builder()

  .setTransport(HTTP_TRANSPORT)
  .setJsonFactory(JSON_FACTORY)
  .setServiceAccountId("xxx@developer.gserviceaccount.com") 
  .setServiceAccountUser(EMAIL_ADRESS)
  .setServiceAccountScopes(CalendarScopes.CALENDAR)
  .setServiceAccountPrivateKeyFromP12File(licenseFile)
  .build();

  client = new com.google.api.services.calendar.Calendar.Builder(
                        HTTP_TRANSPORT, JSON_FACTORY, credential)
                        .setApplicationName("Google Calendar Sync").build();

  Calendar calendar = client.calendars().get(EMAIL_ADRESS).execute();

在最后一行,我收到一个带有消息的 IOException:

ex = (com.google.api.client.auth.oauth2.TokenResponseException) com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request { "error" : "access_denied" }

我重复检查了 GoogleCredential 对象的值,它们是正确的。我还在我的域控制台中添加了https://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/,应用程序 ID 作为客户端授权第三方应用程序访问

我是不是忘记了一步?

4

3 回答 3

3

api还没有完成。更具体地说,服务帐户部分。

日历所有者需要授予应用程序在其日历设置中读取/写入日历的权限。它位于日历的共享设置中,您可以在其中添加帐户的电子邮件地址并授予他们在您的日历上的权限。

因此,在这种情况下,我必须将:xxx@developer.gserviceaccount.com 添加到应用程序需要访问的日历的权限/共享列表中。

由于上述问题,我还删除了另一篇没有完整工作的帖子。我将取消删除它,因为它包含一些将来可能会帮助其他人的代码片段。但请注意不支持 Google 日历的权限问题和服务帐户

于 2013-08-09T13:24:00.610 回答
0

我让它工作

我不知道为什么,但我删除了该行

.setServiceAccountUser(EMAIL_ADRESS)

我还在域范围内添加了一个额外的 url:

https://apps-apis.google.com/a/feeds/calendar/resource/#readonly

并删除了一个不起作用的链接。

最后,我将客户端声明中的 applicationName 更改为与 api 控制台中相同的名称

client = new com.google.api.services.calendar.Calendar.Builder(
                        HTTP_TRANSPORT, JSON_FACTORY, credential)
                        .setApplicationName("HolidaySyncs").build();

在这些步骤之后,它开始工作。

另请注意,在我这样做之后我有以下错误以供将来参考:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "notFound",
    "message": "Not Found"
   }
  ],
  "code": 404,
  "message": "Not Found"
 }
}

我通过改变例如解决了这个问题:

Event result = client.events().insert(<EMAIL ADRESS>, event).execute();

Event result = client.events().insert("primary", event).execute();

首先,我认为谷歌服务器有问题,但是当您尝试链接到日历 ID 时显然会出现问题。因此,链接到作为帐户主日历的“主要”是有效的。但是根据文档,当您引用特定日历 ID 时,它也应该可以工作,其中电子邮件地址是主日历。应该是bug吧?

更新:在这些代码更正之后,我仍然遇到问题。阅读接受的答案以获取更多信息。

于 2012-12-18T15:07:03.887 回答
0

我愿意:

List find = client.events().list(EMAIL_ADRESS);
DateTime timeMin = new DateTime(DateUtil.stringToDate("01/01/2013"));
DateTime timeMax = new DateTime(DateUtil.stringToDate("01/02/2013"));

find.setTimeMin(timeMin);
find.setTimeMax(timeMax);

   try{
       Events events = find.execute();
       int i =0;

       while (true) {
           System.out.println("Page: "+(++i)+": "+events.getItems().size());
         for (Event event : events.getItems()) {
           System.out.println(event.getSummary());
         }
         String pageToken = events.getNextPageToken();
         if (pageToken != null && !pageToken.isEmpty()) {
           events = client.events().list(EMAIL_ADRESS).setPageToken(pageToken).execute();
         } else {
           break;
         }
       }

       }catch(GoogleJsonResponseException e){
           System.out.println(e.getMessage());
//         e.printStackTrace();
       }
于 2013-02-19T14:27:25.493 回答