Google Maps Geocoding API V3 search ok with wifi b

2020-03-07 05:30发布

问题:

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

回答1:

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.



回答2:

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.