我正在尝试联系Google Books API并执行标题搜索,这只需要一个公共的API密钥,而不需要OAUTH2。我得到的只是以下错误:
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "accessNotConfigured",
"message": "Access Not Configured"
}
],
"code": 403,
"message": "Access Not Configured"
}
}
在谷歌上搜索了几个小时后,似乎其他许多人也遇到了同样的问题,但使用了其他谷歌API。到目前为止我所做的:
- 在我的开发人员控制台中注册了一个项目
- 启用书籍API
- 签署我的申请以获得SHA1证书编号
- 选择在我的开发者控制台中获取Android的公共API密钥
- 将以下字符串粘贴到公共API密钥表单中,以便获得密钥:"SHA1 number;com.package",不带引号
- 将生成的密钥复制粘贴到我的代码中
代码如下:
private void callGoogleBooks(){
String key = MY_KEY;
String query = "https://www.googleapis.com/books/v1/volumes?q=flowers+inauthor:keyes&key=" + key;
Log.d("google books", callApi(query));
}
public String callApi(String query){
HttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(query);
HttpResponse httpResponse = null;
try{
httpResponse = httpClient.execute(getRequest);
} catch(UnsupportedEncodingException e){
Log.d("ERROR", e.getMessage());
} catch(ClientProtocolException e){
Log.d("ERROR", e.getMessage());
} catch (IOException e){
Log.d("ERROR", e.getMessage());
}
if(httpResponse != null){
try{
HttpEntity httpEntity = httpResponse.getEntity();
InputStream is = httpEntity.getContent();
BufferedReader br = new BufferedReader(
new InputStreamReader(is, "utf-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine()) != null){
sb.append(line + "n");
}
is.close();
String responseString = sb.toString();
return responseString;
} catch (Exception e){
Log.d("ERROR", e.getMessage());
}
}
return null;
}
- 有任何明显的错误吗?我需要以不同的方式格式化或打包我的请求吗
- 我需要在清单文件中添加任何内容吗
- 在生成公共API密钥时指定包时,是否需要指定与应用程序结构中相同的包名称?我在某个地方读到它必须是唯一的,但把它改成不太可能是重复的东西会导致同样的错误
这个错误显然与"usageLimits"有关,但在我的测试项目中,我甚至还没有接近每天允许的1000个调用的1%。
我还尝试在不使用上面的代码的情况下实现GoogleBooksJavaSample,得到了相同的错误消息。我也尝试过禁用和重新启用图书API,但没有任何运气。
提前谢谢。
这对我有效
String link = "https://www.googleapis.com/books/v1/volumes?q="+params;
InputStream is = null;
try
{
int timeoutConnection = 10000;
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(timeoutConnection);
con.setReadTimeout(timeoutConnection);
con.setRequestProperty("key", "API_KEY");
if(con.getResponseCode() != HttpURLConnection.HTTP_OK){
publishProgress("Error conneting.");
}
is=con.getInputStream();
}
从这个线程:谷歌图书API Android-访问未配置
问题是在为android应用程序设置API密钥限制时,您指定了包名称和SHA-1证书指纹。因此,您的API密钥将仅接受来自指定了程序包名称和SHA-1证书指纹的应用程序的请求。
那么谷歌怎么知道这个请求是从你的安卓应用程序发送的呢?您必须使用以下密钥在每个请求的标题中添加应用程序的包名称和SHA证书:
密钥:"X-Android-Package"
,值:您的应用程序包名称
密钥:"X-Android-Cert"
,值:apk 的SHA-1证书
首先,获取您的应用程序SHA签名(您需要Guava库):
/**
* Gets the SHA1 signature, hex encoded for inclusion with Google Cloud Platform API requests
*
* @param packageName Identifies the APK whose signature should be extracted.
* @return a lowercase, hex-encoded
*/
public static String getSignature(@NonNull PackageManager pm, @NonNull String packageName) {
try {
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
if (packageInfo == null
|| packageInfo.signatures == null
|| packageInfo.signatures.length == 0
|| packageInfo.signatures[0] == null) {
return null;
}
return signatureDigest(packageInfo.signatures[0]);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
}
private static String signatureDigest(Signature sig) {
byte[] signature = sig.toByteArray();
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] digest = md.digest(signature);
return BaseEncoding.base16().lowerCase().encode(digest);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
然后,将包名称和SHA证书签名添加到请求标头:
java.net.URL url = new URL(REQUEST_URL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
try {
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Accept", "application/json");
// add package name to request header
String packageName = mActivity.getPackageName();
connection.setRequestProperty("X-Android-Package", packageName);
// add SHA certificate to request header
String sig = getSignature(mActivity.getPackageManager(), packageName);
connection.setRequestProperty("X-Android-Cert", sig);
connection.setRequestMethod("POST");
// ADD YOUR REQUEST BODY HERE
// ....................
} catch (Exception e) {
e.printStackTrace();
} finally {
connection.disconnect();
}
希望得到帮助!:)