Google Книги API 403 Доступ не настроен

Я пытаюсь связаться с API Google Книг и выполнить поиск по названию, для которого требуется только открытый ключ API, а не OAUTH2. Все, что я получаю, это следующая ошибка:

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

Похоже, что после нескольких часов гуглил, у многих других возникает такая же проблема, но с другими API Google. Что я сделал до сих пор:

  1. Зарегистрировал проект в моей консоли разработчика
  2. Включил API книг
  3. Подпись моей заявки на получение номера сертификата SHA1
  4. Выбран, чтобы получить открытый ключ API для Android в моей консоли разработчика
  5. Вставьте следующую строку в форму ключа открытого API, чтобы получить ключ: "номер SHA1;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 нужно ли указывать то же имя пакета, что и в структуре моего приложения? Я где-то читал, что он должен быть уникальным, но изменение его на что-то менее вероятное дублирование привело к той же ошибке.

Ошибка, по-видимому, связана с "useLimits", но я даже не приблизился к 1% из 1000 вызовов, разрешенных в день в моем тестовом проекте.

Я также пытался реализовать пример Java-книги Google Книги, не используя приведенный выше код, получая то же сообщение об ошибке. Я также безуспешно пытался отключить и снова включить API книг.

Заранее спасибо.

2 ответа

Это сработало для меня

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 Книги API для Android - доступ не настроен

Проблема заключается в том, что при настройке ограничения ключа API для приложения Android вы указали имя пакета и отпечаток сертификата SHA-1. Поэтому ваш ключ API будет принимать запрос только от вашего приложения с указанным именем пакета и отпечатком сертификата SHA-1.

Итак, как Google узнает, что запрос отправлен с вашего Android-приложения? Вы ДОЛЖНЫ добавить имя пакета вашего приложения и сертификат SHA в заголовок каждого запроса со следующими ключами:

Ключ: "X-Android-Package", значение: имя вашего приложения

Ключ: "X-Android-Cert", значение: SHA-1 сертификат вашего apk

Сначала получите подпись 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();
}

Надеюсь, это поможет!:)

Другие вопросы по тегам