我正在构建一个 Android 应用程序并尝试将 Google Books API 集成到我的应用程序中。现在,登录工作。我看到了同意屏幕,其中包含访问我帐户中的 Google 图书数据的请求。我现在正在尝试使用以下代码从我的图书馆中获取所有书架:
public class GetUsernameTask extends AsyncTask<String, Void, Void> {
Activity mActivity;
String mScope;
String mEmail;
public GetUsernameTask(Activity activity, String name, String scope) {
this.mActivity = activity;
this.mScope = scope;
this.mEmail = name;
}
/**
* Executes the asynchronous job. This runs when you call execute()
* on the AsyncTask instance.
*/
@Override
protected Void doInBackground(String... params) {
try {
String token = fetchToken();
if (token != null) {
Log.i("TAG", "Got a token: " + token);
// Use the token to access the user's Google data.
String api_key = params[0];
URL object = new URL("https://www.googleapis.com/books/v1/mylibrary/bookshelves?key=" + api_key);
HttpsURLConnection connection = (HttpsURLConnection) object.openConnection();
connection.setRequestProperty("Authorization", token);
connection.setRequestMethod("GET");
connection.setDoInput(true);
Log.i("TAG", connection.getResponseMessage());
InputStream is = connection.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
Log.i("TAG", line);
}
}
} catch (IOException e) {
Log.e("TAG", "Got an exception", e);
}
return null;
}
/**
* Gets an authentication token from Google and handles any
* GoogleAuthException that may occur.
*/
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException) {
// GooglePlayServices.apk is either old, disabled, or not present
// so we need to show the user some UI in the activity to recover.
Log.i("TAG", "Nu! more exceptions", userRecoverableException);
} catch (GoogleAuthException fatalException) {
// Some other type of unrecoverable exception has occurred.
// Report and log the error as appropriate for your app.
Log.i("TAG", "Nu! more exceptions", fatalException);
}
return null;
}
}
此代码来自 Google 文档 ( https://developers.google.com/android/guides/http-auth )。
作为请求,我附加了“?key=api_key”,由文档(https://developers.google.com/books/docs/v1/using?hl=en#WorkingMyBookshelves)指定,我已经指定了我的令牌标题也是。打印令牌时,它看起来像这样: xxxx.YQJ8nJimB8eeQOIdVkkg2WfkobsBkARzc2TWJL4d_2ipIQuJ4U9uFTvNNhye7i0474TbsA
我得到的结果令人惊讶;这是一个 401 HTTP 错误,即以下内容:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
作为 API 密钥,我尝试使用以下内容:
- 我的 Android 密钥,由https://developers.google.com/mobile/add生成
- 我的 Android 密钥,通过https://console.developers.google.com/生成
- 我的服务器密钥,通过https://console.developers.google.com/生成
我还发现我的硬盘上有两个 debug.keystore 文件,一个在 C:\Android\ 中,一个在 ~\.android 中。我只是决定将两个 SHA-1 哈希添加到两个 Android 密钥(以及 OAuth 2.0 客户端 ID)中,希望它以某种方式使用另一个密钥库 - 无济于事。
我究竟做错了什么?
我也尝试过使用 Google Play Services 库。这会产生不同的错误;但仍然有错误。
我使用此代码(在 doInBackground 方法中)尝试使用所述 API:
try {
Books service = new Books.Builder(AndroidHttp.newCompatibleTransport(), JacksonFactory.getDefaultInstance(), null).setGoogleClientRequestInitializer(new BooksRequestInitializer(api_key)).build();
List<Bookshelf> shelves = service.mylibrary().bookshelves().list().execute().getItems();
}catch (Exception ex){
Log.e("TAG", "Error while using Books", ex);
}
使用 Android 密钥,我收到 403 Forbidden HTTP 响应,并显示消息“在您的 API 密钥上配置了 per-IP 或 per-Referer 限制,并且请求与这些限制不匹配。请使用 Google Developers Console 更新如果应允许来自此 IP 或引用者的请求,则您的 API 密钥配置。”。但是,我在任何地方都看不到使用 Android API 密钥的任何 IP 限制。
使用服务器密钥,我收到 400 Bad Request,可能是因为缺少令牌。
我究竟做错了什么?我错过了什么?