javaandroidposthttpsurlconnectiongoogle-geolocation

FileNotFoundException: https://www.googleapis.com/geolocation/v1/geolocate?key=


I am getting FileNotFoundException in Geolocation API. I have googled it and find that it support only POST method but I am already calling in POST itself.

Please find my code snip here below,

Activity:

String url = "https://www.googleapis.com/geolocation/v1/geolocate?key=API_KEY";
LocationAsyncTask task = new LocationAsyncTask(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
else
    task.execute(url);

AsyncTask:

protected Void doInBackground(String... param) {
    HttpsConnectionHelper conn = new HttpsConnectionHelper(weakContext.get());
    String response = conn.httpPost(param[0]);
    Log.d(MainActivity.LOG_TAG, "LocationAsyncTask = " + response);
    return null;
}

HttpsConnection:

String httpPost(String requestURL) {
        Log.d(MainActivity.LOG_TAG, "HttpsConnectionHelper# requestURL = " + requestURL);
    URL url;
    HttpsURLConnection conn = null;

    try {
        //Create connection
        url = new URL(requestURL);
        conn = (HttpsURLConnection) url.openConnection();
        Log.d(MainActivity.LOG_TAG, "HttpsConnectionHelper# url.openConnection()");

        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Accept", "application/json");
        conn.connect();

        Log.d(MainActivity.LOG_TAG, "HttpsConnectionHelper# conn.connect()");

        //Get Response
        InputStream is = conn.getInputStream();
        Log.d(MainActivity.LOG_TAG, "HttpsConnectionHelper# is.available() = "+is.available());
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuilder response = new StringBuilder();

        while ((line = rd.readLine()) != null) {
            response.append(line);
        }

        rd.close();
        return response.toString();

    } catch (Exception e) {
        e.printStackTrace();
        Log.d(MainActivity.LOG_TAG, "HttpsConnectionHelper#Exception# e.getMessage() = "+e.getMessage());

    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }

    return "";
}

EDIT

Google Geolocation API

curl -X POST "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d \
'{ "homeMobileCountryCode":310,
   "homeMobileNetworkCode":410,
   "radioType":"gsm",
   "carrier":"Vodafone",
   "considerIp":true
}'

This is from official doc. I have written corresponding Android code using this Curl command.

public class GeolocationTask extends AsyncTask<Void, Void, String> {

@Override
protected String doInBackground(Void... params) {
    String apiUrl = "https://www.googleapis.com/geolocation/v1/geolocate?key=API_KEY";
    Log.d(MainActivity.LOG_TAG, "GeolocationTask# doInBackground() apiUrl = " + apiUrl);
    String requestBody = "{ " +
            "\"homeMobileCountryCode\":310, " +
            "\"homeMobileNetworkCode\":410, " +
            "\"radioType\":\"gsm\", " +
            "\"carrier\":\"Vodafone\", " +
            "\"considerIp\":true " +
            "}";

    try {
        URL url = new URL(apiUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // Set up the connection
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        Log.d(MainActivity.LOG_TAG, "GeolocationTask# doInBackground() before write");
        // Write the request body
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = requestBody.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        Log.d(MainActivity.LOG_TAG, "GeolocationTask# doInBackground() after write");

        // Read the response
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine = null;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            Log.d(MainActivity.LOG_TAG, "GeolocationTask# doInBackground() response.toString() = "+response.toString());
            return response.toString();
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.d(MainActivity.LOG_TAG, "GeolocationTask# doInBackground()# Excep = "+e.getMessage());
    }

    return null;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);

    // Handle the result, e.g., parse the JSON response
    if (result != null) {
        // Parse and handle the JSON response here
        Log.d(MainActivity.LOG_TAG, "LocationAsyncTask(new) = " + result);
    }
}

}

But still getting same exception.


Solution

  • The most likely cause of your exception is some kind of error that Geolocation API is returning you as a response. You need to check the response code before calling getInputStream, and process the error accordingly, something like the following:

        int responseCode = connection.getResponseCode();
        if (responseCode != 200) {
            // Get error response
            InputStream errorIs = connection.getErrorStream();
            processError(errorIs);
        } else {
            InputStream is = connection.getInputStream();
            // do whatever you want
        }
    

    You can read HttpURLConnection.html#getErrorStream Javadoc for details and get more ideas from the answers to this question.

    If you are trying to execute literally the same request that is given in the Geolocation API doc, then the error is caused by the wrong API key in the request parameters. Here is the result of running it on my machine:

    C:\Users\evgenye>curl -X POST "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY" -H "Content-Type: application/json" -d '{ "homeMobileCountryCode":310, "homeMobileNetworkCode":410, "radioType":"gsm",    "carrier":"Vodafone",  "considerIp":true}'
    {
      "error": {
        "code": 400,
        "message": "API key not valid. Please pass a valid API key.",
        "errors": [
          {
            "message": "API key not valid. Please pass a valid API key.",
            "domain": "global",
            "reason": "badRequest"
          }
        ],
        "status": "INVALID_ARGUMENT",
        "details": [
          {
            "@type": "type.googleapis.com/google.rpc.ErrorInfo",
            "reason": "API_KEY_INVALID",
            "domain": "googleapis.com",
            "metadata": {
              "service": "geolocation.googleapis.com"
            }
          }
        ]
      }
    }