How to use Google public API access key in android application?
Asked Answered
A

1

3

I want to use Google Translate API (v2) in my android application.

What I did:

  1. created project in Google Developers Console
  2. set up billing for this project
  3. generated 2 public api access keys for android applications:

    a. First one that accepts request from any application

    b. Second one that accepts requests from my application only

I tried to translate text from the application via https://www.googleapis.com/language/translate/v2?key=MY-KEY&target=de&q=Hello%20world

It works fine with the key from 3a) but does not work with the key from 3b). For 3b) server sends

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "ipRefererBlocked",
    "message": "There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed.",
    "extendedHelp": "https://console.developers.google.com"
   }
  ],
  "code": 403,
  "message": "There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed."
 }
}

I guess this is because google server does not receive any info about my application with this request, so it cannot acquire key 3b). If so, how to send this request correctly? Or, alternatively, what I did wrong somewhere else?

Ance answered 4/6, 2015 at 23:37 Comment(0)
C
1

If so, how to send this request correctly?

When setting up your API key restriction for android app, you specified the package name and SHA-1 certificate fingerprint. So when you send an request to Google, you MUST add these information in the header of each request.

HOW?

As answered here, you need to get your package name and SHA certificate from your code, and then adding to request header.

Get SHA certificate:

/**
 * 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;
    }
}

Adding to request header:

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

You can see full answer here.

Enjoy coding :)

Colander answered 17/3, 2017 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.