我正在开发一个基于Android Honeycomb (v3.0)的应用程序,需要与Google日历API进行通信。我想让我的应用程序可以访问特定Google帐户的日历数据,以便读取和创建事件。
不幸的是,我在使用OAuth2时遇到了授权问题。以下是我的进展情况:
1)我想要访问的Google账户的日历已经注册在我正在使用的Android设备中。
2)在账户上启用了Google APIs控制台中的日历API。
3)我能够使用以下代码访问此帐户:
不幸的是,我在使用OAuth2时遇到了授权问题。以下是我的进展情况:
1)我想要访问的Google账户的日历已经注册在我正在使用的Android设备中。
2)在账户上启用了Google APIs控制台中的日历API。
3)我能够使用以下代码访问此帐户:
AccountManager accountManager = AccountManager.get(this.getBaseContext());
Account[] accounts = accountManager.getAccountsByType("com.google");
Account acc = accounts[0]; // The device only has one account on it
4) 我现在希望获取一个AuthToken来用于与日历通信。我按照这篇 教程,但把所有内容都转换为适用于Google Calendar而不是Google Tasks。通过使用getAuthToken
和 AUTH_TOKEN_TYPE == "oauth2:https://www.googleapis.com/auth/calendar"
,我成功地从AccountManager
中检索到了我想要使用的帐户的authToken
。
5) 这里是问题开始的地方。
AccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(tokens[0]); // this is the correct token
HttpTransport transport = AndroidHttp.newCompatibleTransport();
Calendar service = Calendar.builder(transport, new JacksonFactory())
.setApplicationName("My Application's Name")
.setHttpRequestInitializer(accessProtectedResource)
.build();
service.setKey("myCalendarSimpleAPIAccessKey"); // This is deprecated???
Events events = service.events().list("primary").execute(); // Causes an exception!
6) 这里是最后一行返回的异常:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "usageLimits",
"message" : "Daily Limit Exceeded. Please sign up",
"reason" : "dailyLimitExceededUnreg",
"extendedHelp" : "https://code.google.com/apis/console"
} ],
"message" : "Daily Limit Exceeded. Please sign up"
}
7)根据这个Google API视频(等待一分钟左右以获得相关内容)的说明,这种异常发生的原因可能是我未在Google APIs控制台中为该帐户启用API访问权限。但是,如果您查看2),则可以看到我已经这样做了。
8)对我来说,问题似乎在于我无法正确设置Simple API Access Key,因为Calendar.setKey
方法已被弃用。在我之前提供的Google Tasks教程中,使用Tasks.accessKey = "key"
设置密钥。然而,我不确定如何在日历API中使其正常工作。我尝试过多个Google帐户,但所有帐户都出现了第5点的异常。
9)我想指出的是,使用OAuth2的传统方法对我有效。以下是我使用的代码:
HttpTransport TRANSPORT = new NetHttpTransport();
JsonFactory JSON_FACTORY = new JacksonFactory();
String SCOPE = "https://www.googleapis.com/auth/calendar";
String CALLBACK_URL = "urn:ietf:wg:oauth:2.0:oob";
String CLIENT_ID = "myClientID";
String CLIENT_SECRET = "myClientSecret";
String authorizeUrl = new GoogleAuthorizationRequestUrl(CLIENT_ID, CALLBACK_URL, SCOPE).build();
String authorizationCode = "???"; // At this point, I have to manually go to the authorizeUrl and grab the authorization code from there to paste it in here while in debug mode
GoogleAuthorizationCodeGrant authRequest = new GoogleAuthorizationCodeGrant(TRANSPORT, JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, authorizationCode, CALLBACK_URL);
authRequest.useBasicAuthorization = false;
AccessTokenResponse authResponse = authRequest.execute();
String accessToken = authResponse.accessToken; // gets the correct token
GoogleAccessProtectedResource access = new GoogleAccessProtectedResource(accessToken, TRANSPORT, JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, authResponse.refreshToken);
HttpRequestFactory rf = TRANSPORT.createRequestFactory(access);
AccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessToken);
HttpTransport transport = AndroidHttp.newCompatibleTransport();
Calendar service = Calendar.builder(transport, new JacksonFactory())
.setApplicationName("My Application's Name")
.setHttpRequestInitializer(accessProtectedResource)
.build();
Events events = service.events().list("primary").execute(); // this works!
10) 最后,我的问题:我想使用设备上的AccountManager的帐户来检索可用于Google日历API的工作OAuth2令牌。第二种方法对我没有用,因为用户必须手动转到他们的网络浏览器并获取授权代码,这不方便用户。有任何想法吗?抱歉发布了这么长的帖子,谢谢!