Basically I'm trying to let user know when the app cannot reach the server/server down, while their phone internet/data connection is perfectly fine. So I set a timeout by following this post here: How to set HttpResponse timeout for Android in Java
It works great, except when the exception is caught correctly the app still crash instead of displaying the Toast message and return to the app screen. Notice that "Log.e("CONN TIMEOUT", e.toString());" logged correctly in logcat as: "CONN TIMEOUT org.apache.http.conn.ConnectTimeoutException: Connect to /192.168.11.60:80 timed out"
As requested, full logcat: http://pastebin.com/rpe8iKRi
// Making HTTP request
try {
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ConnectTimeoutException e) {
Toast.makeText(getApplicationContext(), "Server timeout", Toast.LENGTH_LONG).show();
Log.e("CONN TIMEOUT", e.toString());
} catch (SocketTimeoutException e) {
Toast.makeText(getApplicationContext(), "Server timeout", Toast.LENGTH_LONG).show();
Log.e("SOCK TIMEOUT", e.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
Log.e("OTHER EXCEPTIONS", e.toString());
}
got it resolved. missing throws Exception { at the end of the function. duhhh
thanks #Alin for good hint.
Related
I am trying to send messages from device to device, without the use of any third part server(Well I do use it for some other parts).
I am using HTTP request to send it to gcm server directly from device.
Heres what I have done.
try {
HttpPost httppost;
try {
httppost = new HttpPost(
"https://android.googleapis.com/gcm/send");
} catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
}
httppost.setHeader("Authorization", "key=512218918480");
httppost.setHeader("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
ArrayList<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new BasicNameValuePair("registration_id", id));
postParams.add(new BasicNameValuePair("data.mode",
"exampleContentOfYourMessage"));
postParams.add(new BasicNameValuePair("m",
"exampleContentOfYourMessage"));
HttpResponse response;
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity entity;
try {
httppost.setEntity(new UrlEncodedFormEntity(postParams, "utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return false;
}
try {
response = httpClient.execute(httppost);
} catch (ClientProtocolException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
entity = response.getEntity();
if (entity != null
&& response.getStatusLine().getStatusCode() == 200) {
return true;
} else {
Log.e("Tag", "No Connection");
return false;
}
} catch (Exception e) {
Log.e("grokkingandroid",
"IOException while sending registration id", e);
}
return false;
}
This returns
02-24 00:19:13.772: W/DefaultRequestDirector(9913): Authentication error: Unable to respond to any of these challenges: {}
So it looks like authentication error for https . DO I need to send something more to gcm server?
I also know the flaws for using this method.My id would be in app so less security.I cant send much data and so on.
I have created the following function for getting json from server as below :
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} 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;
}
}
when user in bad connection, it just loading without give any notification, my question is : how can i add such as toast when request time out or bad connection?
I know, its been A long time, but I try to help, lets try to add this one :
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
and in your code, this will be :
try {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch(ConnectTimeoutException e){
Log.e("Timeout Exception: ", e.toString());
} catch(SocketTimeoutException ste){
Log.e("Timeout Exception: ", ste.toString());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
and to show message request time out, you can add such as alert message on your onPostExecute() if the result null or empty.
First of all set HttpRequestTimeOut like given below then add this logic into try and catch and add toast message into catch block when request timeout fails it'll show you toast message.
url = new URI(s.replace(" ", "%20"));
Log.e("my webservice", "My webservice : " + url);
HttpGet httpget = new HttpGet(url);
HttpResponse httpResponse = null;
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is
// established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
// Execute HTTP Post Request
httpResponse = httpClient.execute(httpget);
I've never really used http requests in Java, I'm trying to make a request that would basically recreate this http://supersecretserver.net:8080/http://whateverwebsite.com
This server takes whatever website and returns only the text of the page in the body of the response.
The code is as follows:
public String getText(String webPage) throws ParseException, IOException{
HttpResponse response = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI("http://supersecretserver.net:8080/" + "http://www.androidhive.info/2012/01/android-text-to-speech-tutorial/"));
response = client.execute(request);
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String responseBody = "No text found on webpage.";
int responseCode = response.getStatusLine().getStatusCode();
switch(responseCode) {
case 200:
HttpEntity entity = response.getEntity();
if(entity != null) {
responseBody = EntityUtils.toString(entity);
}
}
System.out.println("Returning Response..");
System.out.println(responseBody);
return responseBody;
}
It seems to get stuck on
response = client.execute(request);
I'm not sure what the problems is, any insight would be helpful.
Seems likely that your HttpClient is not timing out, you can set a timeout value by following this example (from http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/)
You just to have to consider a timeout value that makes sense for you.
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeoutMillis);
HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);
Also as your HttpClient is not connecting (since it's getting stuck) you should also take into consideration why is that happening (maybe you need to configure a proxy?)
I'm a little confused on how the timeouts in DefaultHttpClient work.
I'm using this code:
private DefaultHttpClient createHttpClient() {
HttpParams my_httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(my_httpParams, 3000);
HttpConnectionParams.setSoTimeout(my_httpParams, 15000);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
ThreadSafeClientConnManager multiThreadedConnectionManager = new ThreadSafeClientConnManager(my_httpParams, registry);
DefaultHttpClient httpclient = new DefaultHttpClient(multiThreadedConnectionManager, my_httpParams);
return httpclient;
}
.
String url = "http://www.example.com";
DefaultHttpClient httpclient = createHttpClient();
HttpGet httpget = new HttpGet(url);
try {
HttpResponse response = httpclient.execute(httpget);
StatusLine statusLine = response.getStatusLine();
mStatusCode = statusLine.getStatusCode();
if (mStatusCode == 200){
content = EntityUtils.toString(response.getEntity());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException e){
e.printStackTrace();
}
When 15 seconds have passed and not all data has been received, an exception will be thrown, right? But on which method? I thought it to be the .execute(httpget) method but that one only tells me it throws ClientProtocolException and IOException. Could anyone help me clearifying this?
It does throw an exception on execute(). The parent of SocketTimeoutException is an IOException. A catch block handling IOException will be able to catch both.
Try executing this code.
HttpParams my_httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(my_httpParams, 3000);
HttpConnectionParams.setSoTimeout(my_httpParams, 1);
DefaultHttpClient defaultHttpClient = new DefaultHttpClient(my_httpParams);
HttpGet httpGet = new HttpGet("http://google.com");
defaultHttpClient.execute(httpGet);
It results in this exception.
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
...
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
You can always choose to selectively process the exception by catching it and handling IOException later.
try
{
// Your code
}
catch (SocketTimeoutException e)
{
// handle timeouts
e.printStackTrace();
}
catch (IOException e)
{
// handle other IO exceptions
e.printStackTrace();
}
If you look at the Apache docs at http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d5e249, it notes that connection timeout exceptions are IOException subclasses.
To be more specific, I believe they'll either ConnectTimeoutExceptions if the connection can't be set up within your configured connection timeout, or SocketTimeoutExceptions, if it's set up but no data is received for your configured SO timeout.
I'm trying to perform a GET request to the server that returns me a JSON file. But I am getting an error in the HTTP statusLine / 422. Anyone know why. Below I show how I'm doing
public void testConverteArquivoJsonEmObjetoJava() {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet(
"http://safe-sea-4024.ppooiheroku4554566adffasdfasdfalaqwerpcp.com/crimes/mobilelist");
get.setHeader("Accept", "application/json");
get.setHeader("Content-type", "application/json");
get.getParams()
.setParameter("token",
"0V1AYFK12SeCZHYgXbNMew==$tRqPNplipDwtbD0vxWv6GPJIT6Yk5abwca3IJ88888a6JhMs=");
HttpResponse httpResponse;
try {
httpResponse = httpClient.execute(get);
String jsonDeResposta = EntityUtils.toString(httpResponse
.getEntity());
System.out.println();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Usually you do not specify a Content-Type header with a GET request. This header tells the server how to interpret the entity includes in the message. It is possible that the server side is expecting a JSON entity even though GET cannot include a body. Try removing the Content-Type header.
I tried the URL that you cleverly changed and got it to work fine. However, I did get a 422 when I specified a different token query parameter. Being that the status line is missing a phrase, I would assume that the Ruby application is generating it.
I managed to solve the problem. I was passing the parameter so wrong. According to this post [blog]:How to add parameters to a HTTP GET request in Android? "link". This method is used to that I kind of POST request
this method is correct
public void testConverteArquivoJsonEmObjetoJava() {
List<NameValuePair> params = new LinkedList<NameValuePair>();
params.add(new BasicNameValuePair("token","0V1AYFK12SeCZHYgXbNMew==$="));
String paramString = URLEncodedUtils.format(params, "utf-8");
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet(
"http://safep.com/crimes/mobilelist" + "?"
+ paramString);
HttpResponse httpResponse;
try {
httpResponse = httpClient.execute(get);
String jsonDeResposta = EntityUtils.toString(httpResponse
.getEntity());
System.out.println();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}`