Google Maps Geocoding API V3 search ok with wifi but responses OVER_QUERY_LIMIT with data connection
Asked Answered
P

2

2

My Google Maps activity searches for addresses with Google Maps Geocoding API V3.
I see that sometimes, even if I repeat the search multiple times in sequence, Google Maps response is OVER_QUERY_LIMIT when I'm connected with data connection.
It also happens on the first search after app's installation on a device.
When I'm connected with wifi it works perfectly.
Here's my code.
Search method:

public static JSONObject getAddressInfo(String sAddress) {
    HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?address=" + sAddress + "&region=it&language=it&sensor=false");
    HttpClient client = new DefaultHttpClient();
    HttpResponse response;
    StringBuilder stringBuilder = new StringBuilder();

    try {
        response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        InputStream stream = entity.getContent();
        int b;
        while ((b = stream.read()) != -1) {
            stringBuilder.append((char) b);
        }
    } catch (ClientProtocolException e) {
    } catch (IOException e) {
    }

    JSONObject jsonObject = new JSONObject();
    try {
        jsonObject = new JSONObject(stringBuilder.toString());
        Log.d("Google Geocoding Response", stringBuilder.toString());
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return jsonObject;
}

Response management:

    JSONObject jsonObject = Utils.getAddressInfo(Utils.strToUrl(inputName.getText().toString().trim()));
    try {
        String sStatus = jsonObject.getString("status");
        if (sStatus.equals("OK")) {
            lng = ((JSONArray)jsonObject.get("results")).getJSONObject(0).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
            lat = ((JSONArray)jsonObject.get("results")).getJSONObject(0).getJSONObject("geometry").getJSONObject("location").getDouble("lat");                     
            bdlData.putDouble("lat", lat);
            bdlData.putDouble("lng", lng);
            bdlData.putFloat("dZoom", dZoom);
            message.setData(bdlData);
            mapHandler.sendMessage(message);
        } else if (sStatus.equals("ZERO_RESULTS")) {
            runMsgOnUIThread("Nessun risultato trovato.");
        } else if (sStatus.equals("OVER_QUERY_LIMIT")) {
            runMsgOnUIThread("Impossibile effettuare la ricerca al momento. Riprovare fra qualche secondo.");
        } else if (sStatus.equals("REQUEST_DENIED")) {
            runMsgOnUIThread("Richiesta non accettata. Riprovare.");
        } else if (sStatus.equals("INVALID_REQUEST")) {
            runMsgOnUIThread("Indirizzo non esistente.");
        } else if (sStatus.equals("UNKNOWN_ERROR")) {
            runMsgOnUIThread("Impossibile effettuare la ricerca al momento. Riprovare.");                   
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
Parcel answered 27/5, 2013 at 9:58 Comment(0)
S
6

Your problem most probably resides in your mobile operator. The vast majority of operators use a technique called NAT overloading and assign the same external IP to a number of devices. If your operator assigns a very large number of devices to a single IP and a number of them uses similar services, everyone will have a problem, as all requests will appear to stem from the same IP.

Your success with the 10*200ms requeries seems to be connected with the expiration of the OVER_QUERY_LIMIT flag from the server-side, as it is implied in this(Usage Limits for Google Maps API Web Services) document, which suggests that upon receiving this status, you should requery after 2secs to see if you exceeded your daily usage or you sent too many requests.

This does not occur through wifi as your phone has its own, more-or-less unique IP.

Soni answered 14/6, 2013 at 13:17 Comment(6)
Thank you for the support! I thought it could be this... The strange thing is that with the same connection: a) the Google Maps app works perfectly; b) the Android Geocoder class works perfectly (I don't actually use it because of other problems)... Now what can I do?Parcel
The Google Maps app is most certainly using Google's client id for their requests, so they will probably have no limit for the app. If the Geocoder Class works properly as well, it is either using that client id too, or throttling and caching requests more efficiently.Soni
I understand. So what do you recommend me to do with this problem? Someone told me not to use the Geocoder class: https://mcmap.net/q/1015100/-geocoder-getfromlocationname-throws-quot-service-not-available-quot-exception-on-android-4-with-google-maps-v2Parcel
aBrav please answer to my last question. Thank you very much.Parcel
There is not much more I can offer you as advice than what is advised on the above article. You may either try and optimise your request handling, throttle it, use the Geocoder class and work with its limitations or get a Maps API for Business licence in that order of preference. Caching alone, if used as described, should improve your success rates at not exceeding your usage quota.Soni
I still don't know how to optimize my request or throttle it or do some caching... Any suggestion?Parcel
P
0

I found a workaround that often (not always) solves the problem: requerying Google every 200 ms if I get OVER_QUERY_LIMIT, for a maximum of 10 times.

Parcel answered 12/6, 2013 at 7:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.