我正在尝试在不使用Google客户端库的情况下连接到Google任务。以下代码返回403禁止错误。只是不确定我错过了什么。任何指导都将不胜感激。
try {
Bundle options = new Bundle();
AccountManager manager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
Account[] list = manager.getAccountsByType("com.google");
Account acct = list[0];
manager.invalidateAuthToken("com.google", null);
AccountManagerFuture<Bundle> acc = manager.getAuthToken(
acct,
"oauth2:https://www.googleapis.com/auth/tasks",
options, true, null, null);
Bundle bundle = acc.getResult();
String token = bundle
.getString(AccountManager.KEY_AUTHTOKEN);
Log.i("Token: ", token); // token does have value
String url = "https://www.googleapis.com/tasks/v1/users/@me/lists?key=long_winded_api_key_from_console_here";
HttpGet getRequest = new HttpGet(url);
getRequest.addHeader("client_id",
"clientID_from_console_here.apps.googleusercontent.com");
getRequest.addHeader("Authorization", "OAuth " + token);
HttpClient httpclient = new DefaultHttpClient();
String responseBody = httpclient.execute(getRequest,
new BasicResponseHandler()); // exception raised here
httpclient.execute(getRequest, new BasicResponseHandler());
Log.i("###", responseBody); // cannot get the response here
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // exception raised here
catch (OperationCanceledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AuthenticatorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
答案 0 :(得分:0)
以下链接显示了如何开始使用Android版Google Drive API。它允许用户选择一个帐户,获得他们的同意然后获取一个凭证对象,该对象可用于使用Google客户端库进行API访问:
https://developers.google.com/drive/quickstart-android
在您的情况下,您尝试使用Tasks API,但身份验证部分应该相同:
在第2步中,改为启用Tasks API。
步骤4显示了如何获取特定范围的访问令牌:
credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
将范围更改为任务API范围:https://www.googleapis.com/auth/tasks
然后我建议您使用Google客户端库,例如云端硬盘示例。
如果由于任何原因您不想使用客户端库,并且更喜欢自己制作HTTP请求,那么您想要的授权标题应如下所示(无法立即测试):
getRequest.addHeader("Authorization", "Bearer " + credential.getToken());
答案 1 :(得分:0)
我不完全确定这是否是原因,因为你似乎做了同样的步骤 我这样做,但你可能想尝试使用“管理你的任务”而不是 的 “的oauth2:https://www.googleapis.com/auth/tasks”即可。这可能是原因 403。
以下是我在没有客户端库的情况下的连接方式。 完整资源来源: apiTalker
首先我获得了访问令牌:
public static final String AUTH_TOKEN_TYPE = "Manage your tasks";
public static String getAuthToken(AccountManager accountManager,
Account account, String authTokenType, boolean notifyAuthFailure) {
Log.d(TAG, "getAuthToken");
String authToken = "";
try {
// Might be invalid in the cache
authToken = accountManager.blockingGetAuthToken(account,
authTokenType, notifyAuthFailure);
accountManager.invalidateAuthToken("com.google", authToken);
authToken = accountManager.blockingGetAuthToken(account,
authTokenType, notifyAuthFailure);
}
catch (OperationCanceledException e) {
}
catch (AuthenticatorException e) {
}
catch (IOException e) {
}
return authToken;
}
连接并列出可用的任务列表:
public static final String BASE_URL = "https://www.googleapis.com/tasks/v1/users/@me/lists";
public static String AuthUrlEnd() {
return "key=" + Config.GTASKS_API_KEY;
}
public static String AllLists(final String pageToken) {
String result = BASE_URL + "?";
if (pageToken != null && !pageToken.isEmpty()) {
result += "pageToken=" + pageToken + "&";
}
result += AuthUrlEnd();
return result;
}
public String getListOfLists(ArrayList<GoogleTaskList> list)
throws ClientProtocolException, IOException, JSONException {
String eTag = "";
String pageToken = null;
do {
HttpGet httpget = new HttpGet(AllLists(pageToken));
httpget.setHeader("Authorization", "OAuth " + authToken);
// Log.d(TAG, "request: " + AllLists());
AndroidHttpClient.modifyRequestToAcceptGzipResponse(httpget);
try {
JSONObject jsonResponse = (JSONObject) new JSONTokener(
parseResponse(client.execute(httpget))).nextValue();
// Log.d(TAG, jsonResponse.toString());
if (jsonResponse.isNull(NEXTPAGETOKEN)) {
pageToken = null;
}
else {
pageToken = jsonResponse.getString(NEXTPAGETOKEN);
}
// No lists
if (jsonResponse.isNull("items")) {
break;
}
eTag += jsonResponse.getString("etag");
JSONArray lists = jsonResponse.getJSONArray("items");
int size = lists.length();
int i;
// Lists will not carry etags, must fetch them individually if
// that
// is desired
for (i = 0; i < size; i++) {
JSONObject jsonList = lists.getJSONObject(i);
//Log.d("nononsenseapps", jsonList.toString(2));
list.add(new GoogleTaskList(jsonList, accountName));
}
}
catch (PreconditionException e) {
// // Can not happen in this case since we don't have any etag!
// } catch (NotModifiedException e) {
// // Can not happen in this case since we don't have any etag!
// }
}
} while (pageToken != null);
return eTag;
}
以下是我解析响应的方法:
public static String parseResponse(HttpResponse response)
throws ClientProtocolException, PreconditionException {
String page = "";
BufferedReader in = null;
Log.d(TAG, "HTTP Response Code: "
+ response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == 403) {
// Invalid authtoken
throw new ClientProtocolException("Status: 403, Invalid authcode");
}
else if (response.getStatusLine().getStatusCode() == 412) { //
/*
* Precondition failed. Object has been modified on server, can't do
* update
*/
throw new PreconditionException(
"Etags don't match, can not perform update. Resolve the conflict then update without etag");
}
/*
* else if (response.getStatusLine().getStatusCode() == 304) { throw new
* NotModifiedException(); }
*/
else if (response.getStatusLine().getStatusCode() == 400) {
// Warning: can happen for a legitimate case
// This happens if you try to delete the default list.
// Resolv it by considering the delete successful. List will still
// exist on server, but all tasks will be deleted from it.
// A successful delete returns an empty response.
// Make a log entry about it anyway though
Log.d(TAG,
"Response was 400. Either we deleted the default list in app or did something really bad");
throw new PreconditionException(
"Tried to delete default list, undelete it");
}
else if (response.getStatusLine().getStatusCode() == 204) {
// Successful delete of a tasklist. return empty string as that is
// expected from delete
Log.d(TAG, "Response was 204: Successful delete");
return "";
}
else {
try {
if (response.getEntity() != null) {
// Only call getContent ONCE
InputStream content = AndroidHttpClient
.getUngzippedContent(response.getEntity());
if (content != null) {
in = new BufferedReader(new InputStreamReader(content));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
page = sb.toString();
//
// System.out.println(page);
}
}
}
catch (IOException e) {
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
return page;
}