I know this question has been asked several times, but still I'm getting this error.
Tried both on emulator and actual device, triend chahging emulator's target to Google API and also changed the target build of the project to Google API's
Need help on these :( Thanks!
I hope you solved it by now. As you said, there are many thread to it. After studying all the threads the answer I got was that Geocoder doesn't always return a value. You can try to send a request 3 times in a for loop. I might be able to return atleast once. If not then, their might be a connection issue or can be other issues like server does not reply to your request.
I had a while loop as well but I used to try it maximum for 10 times. Sometimes, it never returned anything even if it was connected to internet. Then, I used this much more reliable way to get the address everytime:
I used to get the latitude and longitude and then request google servers, to reply with a JSON object containing various information about the location co-ordinates. This way of getting address string does not require Geocoder. Here is the function:
public JSONObject getLocationInfo() {
HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng="+lat+","+lng+"&sensor=true");
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());
} catch (JSONException e) {
e.printStackTrace();
}
return jsonObject;
}
I called it as follows:
JSONObject ret = getLocationInfo();
JSONObject location;
String location_string;
try {
location = ret.getJSONArray("results").getJSONObject(0);
location_string = location.getString("formatted_address");
Log.d("test", "formattted address:" + location_string);
} catch (JSONException e1) {
e1.printStackTrace();
}
Hope this helps. I was also tired of relying on Geocoder. This worked for me. Though it might be just a little slower than geocoder. For testing its functionality, you can just place in the URL with the lat and longitude coordinates you are having. Try to see the returned JSON object in a web browser. You'll see how you can extract the address string. Try and read these threads as well:
Geocoder doesn't always return a value and geocoder.getFromLocationName returns only null
Related
I have some experience in Android application development. Now we developed an Android application where we need the exact date and time from Google or the internet. Already I test some code from Stack Overflow and from some other sites, but it did not work correctly. The app crashed. Can anyone help me?
Try this:
private long getTime() throws Exception {
String url = "https://time.is/Unix_time_now";
Document doc = Jsoup.parse(new URL(url).openStream(), "UTF-8", url);
String[] tags = new String[] {
"div[id=time_section]",
"div[id=clock0_bg]"
};
Elements elements= doc.select(tags[0]);
for (int i = 0; i <tags.length; i++) {
elements = elements.select(tags[i]);
}
return Long.parseLong(elements.text() + "000");
}
Gradle:
compile 'org.jsoup:jsoup:1.10.2'
This is enough to get what you wanted:
Using the HttpGet, Client and Response, I manage to get a server's current time from the response Date Header. I can call this all the times I want and will get confident responses (Google is almost 100% available and I can trust on getting correct Date and Time)
try{
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet("https://google.com/"));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
String dateStr = response.getFirstHeader("Date").getValue();
//Here I do something with the Date String
System.out.println(dateStr);
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
}catch (ClientProtocolException e) {
Log.d("Response", e.getMessage());
}catch (IOException e) {
Log.d("Response", e.getMessage());
}
ou can get time from internet time servers using the below program
import java.io.IOException;
import org.apache.commons.net.time.TimeTCPClient;
public final class GetTime {
public static final void main(String[] args) {
try {
TimeTCPClient client = new TimeTCPClient();
try {
// Set timeout of 60 seconds
client.setDefaultTimeout(60000);
// Connecting to time server
// Other time servers can be found at : http://tf.nist.gov/tf-cgi/servers.cgi#
// Make sure that your program NEVER queries a server more frequently than once every 4 seconds
client.connect("nist.time.nosc.us");
System.out.println(client.getDate());
} finally {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.You would need Apache Commons Net library for this to work. Download the library and add to your project build path.
(Or you can also use the trimmed Apache Commons Net Library here : https://www.dropbox.com/s/bjxjv7phkb8xfhh/commons-net-3.1.jar. This is enough to get time from internet )
2.Run the program. You will get the time printed on your console.
I am developing an application for Android using the text search Google Places API. The goal is to give an address and get the latitude and longitude back so I can mark it on a map.
To do so I send the following request to Google Places :
https://maps.googleapis.com/maps/api/place/textsearch/json?query=46+Rue+Emile+Raspail+Arcueil&sensor=true&key=MY_API_KEY
using this code :
public class GeoLocRDV {
private LatLng pos;
private static final String API_KEY = " xxxxx_MY_KEY ";
private static final String PLACES_TEXT_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/textsearch/json?";
public GeoLocRDV(String rdvPlace){
String url;
try {
url = PLACES_TEXT_SEARCH_URL+"query=" + URLEncoder.encode(rdvPlace,"UTF-8") + "&sensor=true&key=" + API_KEY;
Log.e("DEBUG HTTP", url);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
response = httpclient.execute(new HttpGet(url));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
String responseString = out.toString();
Log.e("DEBUG RESP", responseString);
JSONObject jsonObj = new JSONObject(responseString);
JSONArray results = (JSONArray) jsonObj.get("results");
Log.e("DEBUG JSON", results.toString());
double rdvLat = (Double) results.getJSONObject(0).getJSONObject("geometry").getJSONObject("location").get("lat");
Log.e("DEBUG JSON lat", Float.toString((float) rdvLat));
double rdvLng = (Double) results.getJSONObject(0).getJSONObject("geometry").getJSONObject("location").get("lng");
Log.e("DEBUG JSON lng", Float.toString((float) rdvLng));
this.pos = new LatLng(rdvLat, rdvLng);
Log.e("DEBUG GEO", pos.toString());
}else{
response.getEntity().getContent().close();
}
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
Unfortunately I get this response :
{
"html_attributions" : [],
"results" : [],
"status" : "REQUEST_DENIED"
}
I tried to :
Switch the "sensor" parameter to "true" and "false"
Change https to http
Verify my key was correctly copied/pasted and corresponding to the one in my manifest
I also went to the api console, then to SERVICES, clicked Active services tab and verified 'Places API' is turned ON. Clicked on the ? and "try it out!" link next to it. It also returned me the same JSON (REQUEST_DENIED)
I read on StackOverflow I could try to change the port address to 443 to get response from Places API, but I don't know how to do it.
Finally, I specify that I activated Google Places service after getting my API KEY (because I am also using Maps API) and it is an Android key (not a server or browser), but it is not supposed to be an issue since a key works for a whole application.
I am running out of ideas to fix this request problem, so I hope someone can help me.
Thanks in advance.
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 + "®ion=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();
}
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.
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.
I have this issue that has caused me to pound my head against the wall. I am writing a newspaper app that parses data in JSON from a database and displays it. The app works fine and passes data on WiFi and 4G, but chokes on 3G. Most of the time it takes between 30 seconds and 1 minute to grab data on 3G while only taking one to two seconds on WiFi. I often receive a warning message stating: HttpHostConnectException: Connection refused. I know the site works perfectly fine and is not causing issues because I can query fine on WiFi and 4G along with navigating from a desktop just fine with no problems. As another test, I borrowed my coworkers MiFi which is only on 3G in our area, and connected my device to it, and it passes data just fine although it is only 3G back to the Internet. So after looking at this, and trying to find a solution, I have come to the conclusion that maybe I am not doing something right on my end. To the best of my knowledge, everything is fine, but I am no expert. Any insight on this would be greatly appreciated.
Summary--
4G = Works
WiFI = Works
3G = Extremely slow
3G via WiFi(MiFi on 3G) =Works
public JSONObject makeHttpRequest(String url, String method, List params) {
// Making HTTP request
try {
if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
System.out.println("---GET--- Now grabing GET DATA");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
Is the 3G on my MiFi equally slow? Cause otherwise it sounds like you are saying that your process fails where the connection is slow.
You mention that 3G takes > 30s. Are you running on app engine? GAE has a hard limit on how long transactions can take - I believe that limit is 30s.
What if you added a delay on your server so that even a Wifi request takes as long as 3G tests are taking now - to verify that it is the time taken that is causing the failure.
Also, I think those 3G results sound rather poor. I don't know how much data you are retrieving but it really doesn't sound like it should take that long. So perhaps your 3G connection is simply a poor quality connection (and the MiFi perhaps is a better 3G connection).
I got a valid Json string(at least every onlinevalidator I tried says so) which contains some chinese characters.
The json string is the following:
{"title":"\u8981\u805e--\u83ef\u723e\u8857\u65e5\u5831","url":"http://cn.wsj.com","desc":"\u300a\u83ef\u723e\u8857\u65e5\u5831\u300b\u4e2d\u6587\u7db2\u7d61\u7248\u6700\u65b0\u8ca1\u7d93\u8981\u805e","imageUrl":null,"lastUpdate":"1327588937","items":[{"title":"\u4e16\u8cbf\u7d44\u7e54\u7e3d\u5e79\u4e8b\ufe55\u4eba\u6c11\u5e63\u5e63\u503c\u88ab\u4f4e\u4f30\ufe50\u4f46\u4f4e\u4f30\u7a0b\u5ea6\u4e0d\u660e","desc":"\u4e16\u754c\u8cbf\u6613\u7d44\u7e54\u7e3d\u5e79\u4e8b\u5e15\u65af\u5361\u723e\uff0e\u62c9\u7c73\u9031\u56db\u8868\u793a\ufe50\u4eba\u6c11\u5e63\u532f\u7387\u88ab\u660e\u986f\u4f4e\u4f30\ufe50\u4f46\u4f4e\u4f30\u7a0b\u5ea6\u9084\u4e0d\u6e05\u695a\u3002","url":"http://cn.wsj.com/big5/20120126/BCHc-20120126WR182711424.asp?source=rss","pubdate":null}]}
Now when i Parse the JsonString in Android via new JsonObject(jsonString) I only got some squares instead of characters.
Why cant android handle this json string?
Any help would be apreciated.
If anyone would like to have the server Ressource, it can be found under:
// edit
url removed
public static String test(){
String testResult= "";
try {
HttpGet get = new HttpGet("http://xxxxx");//edit url removed.
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(get);
String result = EntityUtils.toString(response.getEntity());
JSONObject obj = new JSONObject(result);
if(!obj.isNull("title")){
testResult= obj.getString("title");
Log.d("Test","Test1:"+ testResult);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return testResult;//
}
and Then TextView.setText(testResult);
It works for me.
it's Traditional Chinese String:"要聞--華爾街日報"
May be your ROM has no Traditional Chinese font????
When you receive your JSON, you may have to decode the UTF-8 result when you're building your result. Have a look at utf8 decoding. Something similar to this, but with JSON