Android keep trying POST until it goes through - android

I have a POST message I absolutely have to send on Android in a given circumstance, to the point I would like it to keep trying until it completes. I was under the understanding that setting:
urlConnection.setConnectTimeout(0);
would keep trying the connection until it goes through, but what is actually happening is the try block is failing, and the UnknownHostException is being thrown instead:
private class SendAlert extends AsyncTask<String, String, String> {
protected String doInBackground(String... strings) {
Log.d(TAG, "sendAlarm: sending alarm");
String stringUrl = createUri();
HttpsURLConnection urlConnection = null;
BufferedReader reader = null;
String postData = "";
Log.d(TAG, "sendAlarm: apikey: " + apiKey);
try{
Log.d(TAG, "sendAlarm: trying");
URL finalURL = new URL(stringUrl);
urlConnection = (HttpsURLConnection)finalURL.openConnection();
urlConnection.setReadTimeout(10000);
urlConnection.setConnectTimeout(0);
urlConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
urlConnection.setRequestProperty("Accept","application/json");
urlConnection.setRequestProperty("x-api-key",apiKey);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
int responseCode = urlConnection.getResponseCode();
Log.d(TAG, "doInBackground: response code = " + responseCode);
}catch (MalformedURLException e) {
e.printStackTrace();
Log.d(TAG, "doInBackground: error 1 " + e.toString());
}catch(UnknownHostException e){
Log.d(TAG, "doInBackground: e: " + e);
Log.d(TAG, "doInBackground: retrying");
}
catch(Exception e){
Log.d(TAG, "doInBackground: error 2 " + e.toString());
}
Wondering what the best way to set up the post message on Android is, to keep trying the connection until it goes through, even if the phone is on airplane mode for 5 hours.
Edit: going of #user3252344's answer below, is there any problem with calling the function again directly in the catch block of the AyncTask:
catch(UnknownHostException e){
Log.d(TAG, "doInBackground: e: " + e);
Log.d(TAG, "doInBackground: retrying");
SendAlarm sendAlarm = new SendAlarm;
sendAlarm.execute();
}

Setting the connection timeout to 0 will mean it won't timeout, but if it fails to connect it won't handle it still. I'm guessing you get a an UnknownHostException because it fails to resolve the url since it can't reach a DNS server.
I'd suggest you just set a reasonable connection timeout, catch the timeout exception if it happens and re-run.
final int READ_TIMEOUT = 500; // Timeout
final int RETRY_MS = 2000; //Retry every 2 seconds
final Handler handler = new Handler();
Runnable myUrlCall = () -> {
try {
//Make things
urlConnect.setReadTimeout(READ_TIMEOUT);
//Make the URL call, do response
} catch (SocketTimeoutException e) {
handler.postDelayed(myUrlCall, RETRY_MS);
} catch (/* other unintended errors*/ e) {
//Log the error or alert the user
}
};
handler.post(myUrlCall);
Possible even better idea: use Android settings to check if there's internet before you make the call. If there's no internet, use a longer delay. Something like this would be the code you're looking for.

Related

HttpURLConnection.getResponseCode() freezes execution/doesn't time out

I'm writing an Android app that connects to a cPanel server (Apache 2.2.22) page which is password protected. When the authentication credentials are correct, I have no problem connecting. However, when the credentials are incorrect, my Android application seems to freeze in the HttpURLConnection.getResponseCode() method. The logs on the server show hundreds of requests being sent from my Android device, all returning a 401 as expected, but for some reason this is not reflected in my application.
Here is my code, executed from within an AsyncTask:
#Override
protected Integer doInBackground(String... bookInfoString) {
// Stop if cancelled
if(isCancelled()){
return null;
}
Log.i(getClass().getName(), "SendToDatabase.doInBackground()");
String apiUrlString = getResources().getString(R.string.url_vages_library);
try{
NetworkConnection connection = new NetworkConnection(apiUrlString);
connection.appendPostData(bookInfoString[0]);
int responseCode = connection.getResponseCode();
Log.d(getClass().getName(), "responseCode: " + responseCode);
return responseCode;
} catch(IOException e) {
return null;
}
}
This code makes use of my own class NetworkConnection, which is just a basic wrapper class around an HttpURLConnection, to avoid repeating code. Here it is:
public class NetworkConnection {
private String url;
private HttpURLConnection connection;
public NetworkConnection(String urlString) throws IOException{
Log.i(getClass().getName(), "Building NetworkConnection for the URL \"" + urlString + "\"");
url = urlString;
// Build Connection.
try{
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(1000 /* 1 seconds */);
connection.setConnectTimeout(1000 /* 1 seconds */);
} catch (MalformedURLException e) {
// Impossible: The only two URLs used in the app are taken from string resources.
e.printStackTrace();
} catch (ProtocolException e) {
// Impossible: "GET" is a perfectly valid request method.
e.printStackTrace();
}
}
public void appendPostData(String postData) {
try{
Log.d(getClass().getName(), "appendPostData() called.\n" + postData);
Log.d(getClass().getName(), "connection.getConnectTimeout(): " + connection.getConnectTimeout());
Log.d(getClass().getName(), "connection.getReadTimeout(): " + connection.getReadTimeout());
// Modify connection settings.
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
// Get OutputStream and attach POST data.
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
writer.write(postData);
if(writer != null){
writer.flush();
writer.close();
}
} catch (SocketTimeoutException e) {
Log.w(getClass().getName(), "Connection timed out.");
} catch (ProtocolException e) {
// Impossible: "POST" is a perfectly valid request method.
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// Impossible: "UTF-8" is a perfectly valid encoding.
e.printStackTrace();
} catch (IOException e) {
// Pretty sure this is impossible but not 100%.
e.printStackTrace();
}
}
public int getResponseCode() throws IOException{
Log.i(getClass().getName(), "getResponseCode()");
int responseCode = connection.getResponseCode();
Log.i(getClass().getName(), "responseCode: " + responseCode);
return responseCode;
}
public void disconnect(){
Log.i(getClass().getName(), "disconnect()");
connection.disconnect();
}
}
And finally, here is a fraction of the logcat logs:
05-03 11:01:16.315: D/vages.library.NetworkConnection(3408): connection.getConnectTimeout(): 1000
05-03 11:01:16.315: D/vages.library.NetworkConnection(3408): connection.getReadTimeout(): 1000
05-03 11:01:16.585: I/vages.library.NetworkConnection(3408): getResponseCode()
05-03 11:04:06.395: I/vages.library.MainActivity$SendToDatabase(3408): SendToDatabase.onPostExecute(null)
You can see the the method seems to just return null after a random amount of time. The longest I have waited was exactly 15 minutes. There are also several memory logs (GC_CONCURRENT) from dalikvm between the last two info logs which I have omitted.
I should also say that at the moment I am not using https, although I do not believe that should cause any problems. I would be very grateful for any feedback with this, whether it's a complete answer or just a comment telling me what isn't the problem, as I am still unsure whether this problem is server-side or client-side.
Thank you very much,
William
EDIT: I forgot to mention before, I am attaching my authentication credentials with my own custom java.net.Authenticator:
public class CustomAuthenticator extends Authenticator {
Context mContext;
public CustomAuthenticator(Context context){
super();
mContext = context;
}
#Override
protected PasswordAuthentication getPasswordAuthentication() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
String username = sharedPreferences.getString(SettingsActivity.KEY_USERNAME_PREFERENCE, null);
String password = sharedPreferences.getString(SettingsActivity.KEY_PASSWORD_PREFERENCE, null);
return new PasswordAuthentication(username, password.toCharArray());
}
}
which I set in the activity'sonCreate() method:
Authenticator.setDefault(new CustomAuthenticator(mContext));
Also, I have used curl to request the password protected resource, and have received a 401 as expected. I am now assuming the problem is client-side.
It seems to be an issue with using Authenticator in POST connections. It's quite old so I don't know if it still exists.
I would try two things:
Add a log line in the getPasswordAuthentication of the Authenticator to see if it's effectively called. If nothing is printed, you should check that you add the default Authenticator before it's called. You say you do it in the onCreate(), so it should be fine but it's good to be sure.
Avoid using the Authenticator (at least for testing purposes) and send the auth info directly in the HTTP Request. I usually do it this way:
String auth = user + ":" + pass;
conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization",
"Basic " + Base64.encode(auth.getBytes()));
// Set other parameters and read the result...
The problem was that the 401 Unauthorized status is sent when the Authorization header is missing and when the credentials contained within the header are incorrect. Therefore, my app was constantly sending the same request over and over to no avail. I have therefore found a workaround to the problem by adding a counter into my CustomAuthenticator:
public class CustomAuthenticator extends Authenticator {
public static int RETRIES = 3;
int mRetriesLeft;
Context mContext;
public CustomAuthenticator(Context context){
super();
mRetriesLeft = RETRIES;
mContext = context;
}
#Override
protected PasswordAuthentication getPasswordAuthentication() {
Log.i(getClass().getName(), "getPasswordAuthentication() - mCounter: " + mRetriesLeft);
if(mRetriesLeft > 0){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
String username = sharedPreferences.getString(SettingsActivity.KEY_USERNAME_PREFERENCE, null);
String password = sharedPreferences.getString(SettingsActivity.KEY_PASSWORD_PREFERENCE, null);
mRetriesLeft--;
return new PasswordAuthentication(username, password.toCharArray());
} else {
Log.w(getClass().getName(), "No more retries. Returning null");
mRetriesLeft = RETRIES;
return null;
}
}
public void reset(){
mRetriesLeft = RETRIES;
}
}
I should say however that I do not like this solution and therefore, have not accepted it. You have to remember to reset the counter whenever you make a new request (I do it in AsyncTask.onPreExecute()), or else every third request will fail. Also, I'm sure there must be a native way to do this, although after scouring the documentation I can't find it. I would still be very grateful if anyone can point it out to me.
I don't know if I am right or not but my solution has worked for me for a whole day without a glitch.
Try doing this
byte[] buf = new byte[4096];
Inputstream is;
do
{
http conn code etc;
is=conn.getInputStream();
if(is.read(buf)==0)
{
flag=1;
}
//u can either is.close(); or leave as is
//code
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
conn.disconnect();
} while(flag==1);

Android: Quick web requests

For my application I need to have the latest data from an webpage that is hosted on a server on my local network.
So I request the latest page with a HTTP GET and when the data is received, I send another request.
With my current implementation I reach around the 100 - 120 ms per request. Is there a possibility to make this quicker because it's the same url that is requested.
For example keep the connection open to the page and grep the latest data without setting up a new connection?
This page is around the 900-1100 bytes.
HTTP get code:
public static String makeHttpGetRequest(String stringUrl) {
try {
URL url = new URL(stringUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(300);
con.setConnectTimeout(300);
con.setDoOutput(false);
con.setDoInput(true);
con.setChunkedStreamingMode(0);
con.setRequestMethod("GET");
return readStream(con.getInputStream());
} catch (IOException e) {
Log.e(TAG, "IOException when setting up connection: " + e.getMessage());
}
return null;
}
Reading inputstream
private static String readStream(InputStream in) {
BufferedReader reader = null;
StringBuilder total = new StringBuilder();
try {
String line = "";
reader = new BufferedReader(new InputStreamReader(in));
while ((line = reader.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
Log.e(TAG, "IOException when reading InputStream: " + e.getMessage());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return total.toString();
}
As I know there isn't an implementation like you are asking for. I've been dealing a lot with http requests and the best thing you can do is your code. There is another thing which need some attention...your connection maybe slow and depending on that connection time can be more or in some cases which I've been dealing a lot the connection's timeout isn't enough big, but that's server problem.
In my opinion you should use what you have now.

Android httpUrlConnection connecting to server but not internet

I am working on an application that uses HttpUrlConnection, connects beautifully with the server, but when fetching data from it says connection time out IOException.
The internet, & network permissions are already set in the android.manifest; there are no bars showing up in the android emulator (does this says anything).
Read at developer.android.com:
The functional limitations of the emulator include:
- No support for determining network connected state
- and few others....
Any help will be highly appreciated. And I don't have an actual device to test this.
Received server info do gets printed in the logcat.
Thanks...
Here is the code:
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
try {
Log.i(INFO_TAG, "Received server:" + conn.toString());
conn.setInstanceFollowRedirects(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-length", "0");
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setConnectTimeout(25000 /* milliseconds */);
conn.setReadTimeout(15000/* 10000 *//* milliseconds */);
// conn.setDoInput(true);
// Starts the query
conn.connect();
status = conn.getResponseCode();
Log.d(DEBUG_TAG, "Status recevied is: " + conn.getResponseCode());
responseCode = status;
if (responseCode == 200) {
Log.i(INFO_TAG, "URL Connection OK");
contentIs = conn.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(contentIs));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
Log.i(INFO_TAG, "Data Read is: " + line);
}
} else {
Log.d(DEBUG_TAG, "Could not read data from web server");
Log.e(ConnectAndGetData.class.toString(),
"Failed to download content");
}
}// end of try
catch (Exception ex) {
// This is currently being printout
Log.d(DEBUG_TAG, "Received an exception" + ex.toString(), ex);
ex.printStackTrace();
throw new IOException("Error Connecting" + ex.toString());// "Error connecting");
} finally {
if (contentIs != null) {
contentIs.close();
conn.disconnect();
}
}
One more thing since, it throws a connection timeout exception it does not debug info at this line is printed:
Log.d(DEBUG_TAG, "Status recevied is: " + conn.getResponseCode());
You need to write
conn.setDoInput( true ); after this line
conn.setConnectTimeout(25000 /* milliseconds */);
conn.setReadTimeout(15000/*10000*/ /* milliseconds */);
Its Sets the flag indicating whether this URLConnection allows input.
The emulator can't receive any response from server. I think the problem with your network connection. Check your proxy settings.
The problem was not the code above, it was the server code (the main culprit). Now implemented a web service and the code above is working fine.
Thanks all for commenting...

DefaultHttpClient change response size?

What I try to do
Hello Guys, I'm trying to create an App in which I can view the Orders the Customers gave to me. For this I created a interface on my server, on which I can send post/get/set request's. The response of the Server is in JSON-Format. (For your Information atm only dummydata is filled in)
Now when I do a get request from my app to the server, I get a response from it but it isn't complete about the half of the response I should get isn't there! :( But when I open the URL with the Get-Request in my browser, I get the full response.
Question
Like you see it can't be a server-based problem, because I also tryed via 'curl' to do this get requst, and allways got the full response.
In my App i work with the DefaultHttpClient, so I tought the Problem simply could be that there's a limit for the response but I didn't found it.
So where can I change this "response-size" and what else could be the problem why I don't get the full response! Some good code-snippets or whatever you can imagine would help!
Down here you'll find the code of the Methode which does the Get-Request.
Code
If you need more Code, just write it in the comments!
getOrders()
public void getOrders() {
Log.d("DataHandlerService", "Aufträge werden geladen");
Thread t = new Thread() {
public void run() {
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String userid = settings.getString("userid", "uid");
Log.d("DataHandlerService", userid);
// Download-URL
String URL = "http://api.i-v-o.ch/users/" + userid
+ "/assignments.json";
Log.d("Request-URL", URL);
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response;
try {
HttpGet request = new HttpGet();
request.setURI(new URI(URL));
request.addHeader("Content-Type",
"application/x-www-form-urlencoded");
response = client.execute(request);
int statuscode = response.getStatusLine().getStatusCode();
switch (statuscode) {
case 200:
if (response != null) {
StringBuilder sb = new StringBuilder();
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity()
.getContent()));
String line;
while ((line = rd.readLine()) != null) {
sb.append(line + "\n");
}
String result;
result = sb.toString();
Log.d("Response", result);
JSONReader(result); //here the json will be generated
}
break;
case 500:
// Error-Handling
break;
}
} catch (Exception e) {
e.printStackTrace();
Log.e("DataHandler", "URLConnection-Error" + e);
}
}
};
t.start();
}
Here's the Response you asked for, like you see a part of it isn't there!:
[{"created_at":"2012-01-06T17:10:00Z","end_datetime":"2008-03-25T13:00:00Z","id":2127,"start_datetime":"2008-03-25T13:00:00Z","updated_at":"2012-01-06T17:10:00Z","title":"2127 Foobar","referee_forename":"Peter","referee_surname":"Gertsch","referee_full_name":"Peter Gertsch","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:03Z","end_datetime":"2008-04-04T12:00:00Z","id":2134,"start_datetime":"2008-04-04T12:00:00Z","updated_at":"2012-01-06T17:10:03Z","title":"2134 Foobar","referee_forename":"Daniel","referee_surname":"Brunner","referee_full_name":"Daniel Brunner","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:03Z","end_datetime":"2008-04-07T12:00:00Z","id":2136,"start_datetime":"2008-04-07T12:00:00Z","updated_at":"2012-01-06T17:10:03Z","title":"2136 Foobar","referee_forename":"Andreas","referee_surname":"Lutz","referee_full_name":"Andreas Lutz","category_title":"Installation - SAT","status_title":"Closed - technisches problem"},{"created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-05-22T07:00:00Z","id":2144,"start_datetime":"2008-05-22T07:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2144 Foobar","referee_forename":"Pascal","referee_surname":"Pichand","referee_full_name":"Pascal Pichand","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-05-15T07:00:00Z","id":2145,"start_datetime":"2008-05-15T07:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2145 Foobar","referee_forename":"Hansruedi","referee_surname":"W\u00fcrgler","referee_full_name":"Hansruedi W\u00fcrgler","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-05-26T08:00:00Z","id":2146,"start_datetime":"2008-05-26T08:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2146 Foobar","referee_forename":"Martina","referee_surname":"Issler","referee_full_name":"Martina Issler","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-06-03T14:00:00Z","id":2147,"start_datetime":"2008-06-03T14:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2147 Foobar","referee_forename":"Matthias ","referee_surname":"Kuhn","referee_full_name":"Matthias Kuhn","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:12Z","end_datetime":"2008-07-07T07:00:00Z","id":2157,"start_datetime":"2008-07-07T07:00:00Z","updated_at":"2012-01-06T17:10:12Z","title":"2157 Foobar","referee_forename":"Eberhard","referee_surname":"Polatzek","referee_full_name":"Eberhard Polatzek","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:13Z","end_datetime":"2008-07-11T08:00:00Z","id":2161,"start_datetime":"2008-07-11T08:00:00Z","updated_at":"2012-01-06T17:10:13Z","title":"2161 Foobar","referee_forename":"Magali","referee_surname":"Bohin","referee_full_name":"Magali Bohin","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:14Z","end_datetime":"2008-07-25T08:30:00Z","id":2163,"start_datetime":"2008-07-25T08:30:00Z","updated_at":"2012-01-06T17:10:14Z","title":"2163 Foobar","referee_forename":"(Hotel Centrum Griesalp)","referee_surname":"Haltenegg Betriebs AG","referee_full_name":"(Hotel Centrum Griesalp) Haltenegg Betriebs AG","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:16Z","end_datetime":"2008-08-07T09:00:00Z","id":2170,"start_datetime":"2008-08-07T09:00:00Z","updated_at":"2012-01-06T17:10:16Z","title":"2170 Foobar","referee_forename":".","referee_surname":"SAC Hollandiah\u00fctte","referee_full_name":". SAC Hollandiah\u00fctte","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich"},{"created_at":"2012-01-06T17:10:16Z","end_datetime":"2009-05-07T06:30:00Z","i
Ah. Right, the problem isn't your connection or anything like that. Your service is returning an array - not an object - thus you should parse it like this:
HttpResponse response = ...
if (.. validate status ..) {
JSONArray array = new JSONArray(HttpEntityUtils.toString(response.getEntity()));
// Your JSONArray is now ready to play with.
}
And consider using an AsyncTask instead of a Thread, like this:
class AssignmentsTask extends AsyncTask<String, Void, JSONArray> {
#Override
protected JSONArray doInBackground(String... params) {
final String url = "http://api.i-v-o.ch/users/" + params[0]
+ "/assignments.json";
try {
HttpResponse response = mClient.execute(new HttpGet(url));
if (response.getStatusLine().getStatusCode() == 200) {
return new JSONArray(EntityUtils.toString(response.getEntity()));
} else {
Log.w(TAG, "Error receiving assignments for " + params[0] + ", " + response.getStatusLine());
}
} catch (ClientProtocolException e) {
Log.w(TAG, "Proto: Error fetching assignments for " + params[0], e);
} catch (IOException e) {
e.printStackTrace();
Log.w(TAG, "IO: Error reading assignments for " + params[0], e);
} catch (ParseException e) {
Log.w(TAG, "Parse: Error parsing assignments for " + params[0], e);
} catch (JSONException e) {
Log.w(TAG, "JSON: Error parsing JSON for " + params[0], e);
}
return null;
}
#Override
protected void onPostExecute(JSONArray result) {
// Stuff that handles the resulting JSONObject on
// the UI-thread goes here (i.e. update View:s)
// result is null if the operation failed
}
}
And to retrieve an order for the user "116":
new AssignmentsTask().execute("116");
The response size should be given by the web server you are contacting. You could read the response size using :
httpResponse.getEntity().getContentLength()
Also, what can happen is a connection timeout, making it impossible for the client to receive all data of the response. In that case, try using a timeout that is long enough to be sure you get all the data.
If your json is too large, then it's not a good idea in a mobile context to expect all the data coming in a single request, you could then have to design a web server that could give you chunks of a response, you would then require the first chunk, then the a different one, etc..
Usually, the http protocole's partial content is the answer for that problem.

Android display my own error message ifrom an exception

i have implemented a try block that does some network requests but whenever it throws an exception such has a Timeout one, the android application displays a message Saying
Sorry: The application has stopped unexpectedy, please try again.
the only option presented to the user is a force close button. i want to catch this exception and simple display my own error message and let the user try the connection again instead of the user having to close the app.
Here is the code below:
all i want to do is return null after a exception is caught and what ever class that calls this will do it its own error handling like this:
if(postRequest == null){ display error message}
private HttpResponseObject PostRequest() {
//int response = 0;
String responseBody = "";
HttpResponseObject response = new HttpResponseObject();
try {
Log.d(TAG, "IN POST_REQUEST_METHOD");
Log.d(TAG, "URL : " + url);
httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1);
//httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);
httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5);
Log.d(TAG, "httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);");
post = new HttpPost(url);
// ClientConnectionRequest connRequest = new ManagedClientConnection();
// post.setConnectionRequest((ClientConnectionRequest) connRequest.getConnection(3000, TimeUnit.MILLISECONDS));
ByteArrayEntity entity = new ByteArrayEntity(data.getBytes());
entity.setChunked(true);
post.setEntity(new StringEntity(data));
HttpResponse httpResponse = httpclient.execute(post);
HttpEntity resEntity = httpResponse.getEntity();
if (resEntity != null) {
// indicate that the content of this entity is no longer
// required
response.setResponseBody(EntityUtils.toString(resEntity));
Header[] header = httpResponse.getAllHeaders();
Log.d(TAG, "httpResponse.getAllHeaders() = " + header[0].getName());
response.setResponseHeader(httpResponse.getAllHeaders().toString());
resEntity.consumeContent();
}
// release all recources from the httpClient object
httpclient.getConnectionManager().shutdown();
response.setResponseCode(httpResponse.getStatusLine().getStatusCode() ) ;
Log.d(TAG, "responseBody = " + response.getResponseBody());
Log.d(TAG, "response code = " + response.getResponseCode());
Log.d(TAG, "response header = " + response.getResponseHeader());
return response;
} catch (SocketTimeoutException e) {
e.printStackTrace();
Log.d(TAG, "SocketTimeoutException e = " + e.toString());
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d(TAG, "IOException e = " + e.toString());
return null;
}
}
The Force Close dialog appears due to an uncaught exception. Since you are not throwing a checked exception yourself, this is due to a runtime exception, most probably a Null Pointer one. This means that there is bug in your code that causes this and not a network error.
In order to find the problem you need to know the type of the Exception being thrown and its message. You can see these at the LogCat - if you are using Eclipse it is available in the debug perspective.

Categories

Resources