【问题标题】:Google Books API 403 Access Not ConfiguredGoogle Books API 403 访问未配置
【发布时间】:2014-01-22 10:50:54
【问题描述】:

我正在尝试联系 Google Books API 并执行标题搜索,它只需要一个公共 API 密钥,不需要 OAUTH2。我得到的只是以下错误:

{
    "error": {
        "errors": [
        {
            "domain": "usageLimits",
            "reason": "accessNotConfigured",
            "message": "Access Not Configured"
        }
        ],
        "code": 403,
        "message": "Access Not Configured"
    }
}

在谷歌上搜索了几个小时后,似乎许多其他人也遇到了同样的问题,但使用的是其他 Google API。到目前为止我做了什么:

  1. 在我的开发者控制台中注册了一个项目
  2. 启用图书 API
  3. 签署我的申请以获得 SHA1 证书编号
  4. 选择在我的开发者控制台中获取 Android 的公共 API 密钥
  5. 将以下字符串粘贴到公共 API 密钥表单中,以获取密钥:“SHA1 number;com.package”,不带引号
  6. 将生成的密钥复制粘贴到我的代码中。

代码如下:

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%。

我也尝试在不使用上面的代码的情况下实现Google Books Java Sample,得到相同的错误消息。我还尝试禁用和重新启用 Books API,但没有任何运气。

提前致谢。

【问题讨论】:

    标签: android google-api google-api-java-client google-books


    【解决方案1】:

    这对我有用

    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();
    }
    

    来自这个帖子:Google Books API for Android - Access Not Configured

    【讨论】:

      【解决方案2】:

      问题是在为 Android 应用设置 API 密钥限制时,您指定了包名称和 SHA-1 证书指纹。因此,您的 API 密钥将仅接受来自您的应用的请求,并指定了包名称和 SHA-1 证书指纹。

      那么 google 是如何知道该请求是从您的 ANDROID 应用程序发送的?您必须使用以下键在每个请求的标头中添加应用的包名称和 SHA 证书:

      Key:"X-Android-Package",value:你的应用包名

      密钥:"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();
      }
      

      希望对您有所帮助! :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-12
        • 2014-01-24
        • 1970-01-01
        • 2014-01-16
        • 1970-01-01
        • 1970-01-01
        • 2013-04-30
        • 1970-01-01
        相关资源
        最近更新 更多