Search code examples
javaandroidweb-servicesgoogle-mapshttp-status-code-403

Android: Getting HTTP 403 Forbidden upon calling https://maps.googleapis.com/maps/api/geocode/json


I have been trying to use the Google api, more specifically this URL to get the U.S State and city and I keep on getting a 403 Forbidden HTTP error message, My code goes as follows:

private static boolean getAddressResult(String input, StringBuilder jsonResults) {
    HttpURLConnection conn = null;
    try {

        String mapUrl;
        StringBuilder sb = new StringBuilder(https://maps.googleapis.com/maps/api/geocode/json);
        sb.append("?sensor=false&address=" + URLEncoder.encode(input, "utf8"));

        mapUrl = sb.toString();

        URL url = new URL(mapUrl);

        Logger.d(TAG, ""+ url);
        Logger.d(TAG, "trying to read");

        conn = (HttpURLConnection) url.openConnection();


        int status = conn.getResponseCode();

        Logger.d(TAG, "status: "+ status);
        InputStreamReader in = new InputStreamReader(conn.getInputStream());

        // Load the results into a StringBuilder
        int read;
        char[] buff = new char[1024];
        long currentTime = System.currentTimeMillis();

        while ((read = in.read(buff)) != -1) {
            Logger.d("NetworkUtil", "trying to parse");

            long elapsedTime = System.currentTimeMillis();
            if(elapsedTime-currentTime>=5000)
                return false;
            jsonResults.append(buff, 0, read);
        }
    } catch (MalformedURLException e) {
        Logger.e(LOG_TAG, "Error processing Places API URL", e);
        return true;
    } catch (IOException e) {
        Logger.e(LOG_TAG, "Error connecting to Places API", e);
        return true;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
    return false;
}

I have tried different alternatives including changing the URL from HTTP to HTTPS, I am not sure of exactly what I am missing at this point, there have been few instances where this web service call came back with a 200 success but most of the time it just fails with a 403 HTTP ERROR code, any advice would be helpful at this point, I am also attaching a Log from Logcat:

 Error connecting to Places API
java.io.FileNotFoundException: https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=08080
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
        at .getAddressResult(NetworkUtil.java:217)
        at .access$000(NetworkUtil.java:30)
        at $ResolveCityTask.doInBackground(NetworkUtil.java:81)
        at $ResolveCityTask.doInBackground(NetworkUtil.java:42)

Solution

    1. The sensor parameter is no longer required.
    2. Also you did not provide a API_KEY in your request url.
    3. the StringBuilder's string should be surround by double quotes.
    4. Your address string from the logcat is 08080, which should be a characters string.
    5. You should perform your API request in background thread.

    A sample API require URL should be like this: https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=API_KEY

    Sample modified code:

    String API_KEY = "YOUR_API_KEY_STRING";
    String input = "1600+Amphitheatre+Parkway,+Mountain+View,+CA";
    
    private static boolean getAddressResult(String input, StringBuilder jsonResults) {
        try {
    
            URL requestUrl = new URL("https://maps.googleapis.com/maps/api/geocode/json?address=" + input " + &key=" + API_KEY;
                );
            HttpURLConnection connection = (HttpURLConnection)requestUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
    
    
            responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
    
                BufferedReader reader = null;
    
                InputStream inputStream = connection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                if (inputStream == null) {
                    // Nothing to do.
                    return false;
                }
                reader = new BufferedReader(new InputStreamReader(inputStream));
    
                String line;
                while ((line = reader.readLine()) != null) {
                    long elapsedTime = System.currentTimeMillis();
                    if(elapsedTime-currentTime>=5000) {
                       return false;
                    }
                    buffer.append(line + "\n");
                }
    
                if (buffer.length() == 0) {
                    return false;
                }
    
                Log.d("Test", buffer.toString());
                return buffer.toString();
            }
            else {
                Log.i(TAG, "Unsuccessful HTTP Response Code: " + responseCode);
                return false
            }
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
            return false;
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error connecting to Places API", e);
            return false;
        } catch (Expcetion e) {
            return false;
        }
        return false;
    }
    

    This sample code should be run inside your background method.

    also need to make sure add internet permission in your manifest file. <uses-permission android:name="android.permission.INTERNET" />

    You can also check your internet connectivity by adding <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> and call this method to see if your internet is connected:

     private boolean isNetworkAvailable() {
            ConnectivityManager manager = (ConnectivityManager)
                    getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
    
            boolean isAvailable = false;
            if (networkInfo != null && networkInfo.isConnected()) {
                isAvailable = true;
            }
            return isAvailable;
        }