Android: use HttpsUrlConnection for upload and get response but got SocketTimeoutException - android

I have a server with SSL certificate.
And I am using functions uploadFileHttps(...) to upload an image and get corresponding response with HttpsUrlConnection.
For the upload part, it sent out the image data through output stream.
However, server haven't received that image. Also, when it is trying to obtain response from server through input stream.
It catches an exception "java.net.SocketTimeoutException: Read timed out"
How could I fix it?
private static final int CONNECTION_TIMEOUT = 20000;
private static final int IMAGE_UPLOAD_TIMEOUT = 60000;
private void uploadFileHttps(File file, String requestURL) {
HttpsURLConnection connection = null;
try {
//requestURL is a https link like: https://test.abcde.com/upload
connection = (HttpsURLConnection) new URL(requestURL).openConnection();
connection.setHostnameVerifier(new NullHostNameVerifier());
connection.setConnectTimeout(CONNECTION_TIMEOUT);//timeout for handshake
connection.setReadTimeout(IMAGE_UPLOAD_TIMEOUT);//timeout for waiting read data
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "image/jpeg");
Token.setAuthTokenHeader(connection, context);
connection.setDoOutput(true);//set to use httpURLConnection for output
connection.connect();
//upload file to server
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
int bytesRead;
byte buf[] = new byte[1024];
BufferedInputStream bufInput = new BufferedInputStream(new FileInputStream(file));
while ((bytesRead = bufInput.read(buf)) != -1) {
// write output
out.write(buf, 0, bytesRead);
out.flush();
}
out.flush();
out.close();
//get response from server
BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
StringBuilder sb = new StringBuilder();
String output;
while ((output = br.readLine()) != null) {
sb.append(output);
}
System.out.println(sb.toString());
} catch (Exception e) {
if (e != null)
e.printStackTrace();
} finally {
if (connection != null) connection.disconnect();
}
}
class NullHostNameVerifier implements HostnameVerifier {
#Override
public boolean verify(String hostname, SSLSession session) {
Log.i("RestUtilImpl", "Approving certificate for " + hostname);
return true;
}
}
Stack Trace for error
W/System.err﹕ java.net.SocketTimeoutException: Read timed out
W/System.err﹕ at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:689)
W/System.err﹕ at java.io.InputStream.read(InputStream.java:162)
W/System.err﹕ at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142)
W/System.err﹕ at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
W/System.err﹕ at com.android.okhttp.internal.Util.readAsciiLine(Util.java:316)
W/System.err﹕ at com.android.okhttp.internal.http.RawHeaders.fromBytes(RawHeaders.java:308)
W/System.err﹕ at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:135)
W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:644)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
W/System.err﹕ at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.uploadFileSSL(HttpRequestTask.java:355)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.doRequest(HttpRequestTask.java:152)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.doInBackground(HttpRequestTask.java:182)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.doInBackground(HttpRequestTask.java:47)
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err﹕ at java.lang.Thread.run(Thread.java:841)

connection.setRequestMethod("PUT");
This sets the request method to PUT.
connection.setDoOutput(true);//set to use httpURLConnection for output
This sets the request method to POST. You need to execute this before the PUT line above.

Related

HTTP-request throws an exception FileNotFound

I have url: http://xxx.xxx.xxx.xxx:yyyy/api/Account/Register (ip:port). And in the browser I can get it like POST method without any problems. But Android throws an exception:
W/System.err: java.io.FileNotFoundException:
http://xxx.xxx.xxx.xxx:yyyy/api/Account/Register W/System.err: at
com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
W/System.err: at
com.contedevel.reserves.utils.RestApi.signUp(RestApi.java:37)
W/System.err: at
com.contedevel.reserves.activity.RegisterActivity$UserRegistrationTask.doInBackground(RegisterActivity.java:415)
W/System.err: at
com.contedevel.reserves.activity.RegisterActivity$UserRegistrationTask.doInBackground(RegisterActivity.java:396)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err: at
java.util.concurrent.FutureTask.run(FutureTask.java:237) W/System.err:
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err: at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err: at
java.util.concurrent.ThreadPoolExecutor$Wo9191rker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:841)
A request method is POST 100%.
I create a new connection so:
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
Write arguments so:
OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
final String body = builder.toString();
writer.write(body);
writer.flush();
writer.close();
os.close();
What could be the problem?

Https url is not working but http url is working fine in android

Please guide me to find the problem in this code, when i use url with HTTP then it works fine but with HTTPS it's giving problem.I have googled but couldn't find a solution. It would be appreciable if someone guide me to save my time Thanks
public String doRequest() {
String serverUrl = Constants.BASE_URL + mAction;
Log.d("usm_serverUrl",serverUrl);
if (mParams != null) {
serverUrl += "?" + mParams;
}
Log.d("usm_serverUrl",serverUrl);
try {
URL url = new URL(serverUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestProperty("User-Agent", "application/json");
conn.setRequestMethod("GET");
if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){
// Do normal input or output stream reading
Log.d("usm_requestCode","Successful");
}
else {
Log.d("usm_requestCode","Failed");
// response = "FAILED"; // See documentation for more info on response handling
}
//HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(conn.getInputStream());
Log.d("debug", "get-url: " + serverUrl);
String response = IOUtils.toString(in, "UTF-8");
Log.d("debug", "get-url: " + serverUrl + "\n post-response: " + response);
return response;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I'm getting the following exception:
11-30 22:43:30.553 5031-5398/com.dhcollator.routetoschool W/System.err﹕ javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.Connection.upgradeToTls(Connection.java:146)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.Connection.connect(Connection.java:107)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
11-30 22:43:30.554 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
11-30 22:43:30.555 5031-5398/com.dhcollator.routetoschool W/System.err﹕ at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
For https url connection to work in android, use HttpsUrlConnection instead of HttpUrlConnection.
See Documentation here
refer link, it will help as HttpsUrlConnection is required instead of HttpUrlConnection.
http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html
http://www.java-samples.com/java/POST-toHTTPS-url-free-java-sample-program.htm

Android code to send http request to a local server

I have implemented HttpUrlConnection to send a request to a local http server (common LAN,Wifi,WifiAP). The code works perfectly fine for normal web servers (www.xyz.com), but fails to do so for local servers (192.168.x.y:z).
The code:
1) The function which makes the request
public static String getDef(String urlInput) {
URL url = null;
try {
url = new URL("http://" + urlInput);
Log.d("http", "calling " + url.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Connection", "close");
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.connect();
InputStream in = null;
in = (conn.getInputStream());
String response =readIt(in,5) ;
//response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
return response;
} catch (IOException e) {
Log.e("http","Error");
e.printStackTrace();
}
return "LocalClient didnt work";
}
2) The function which calls the above function.
new AsyncTask<String, Void, String>(){
#Override
protected String doInBackground(String... params){
try {
return LocalClient.getDef(URL);
} catch (Exception e){
e.printStackTrace();
}
return "Didnt work";
}
#Override
protected void onPostExecute(String string) {
message.append(string);
}
}.execute();
3)The request is received at the server with the following headers.
GET / HTTP/1.1
Connection: close
User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 5 Build/LYZ28E)
Host: 192.168.0.101
Accept-Encoding: gzip
It would be wonderful if someone could point me in the right direction.
I have also tried OkHttp,
public static String get(String url) throws IOException {
OkHttpClient client = new OkHttpClient();
try {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
resp= response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return resp;
}
On using a normal webserver the response is properly returned (source) but while using a local server I get the following error
java.io.EOFException
W/System.err﹕ at com.android.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:95)
W/System.err﹕ at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:179)
W/System.err﹕ at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:101)
W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:628)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:388)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:199)
W/System.err﹕ at com.demo.demo.http.LocalClient.getDef(LocalClient.java:56)
W/System.err﹕ at com.demo.demo.wifi.connector$2$2.doInBackground(connector.java:109)
W/System.err﹕ at com.demo.demo.wifi.connector$2$2.doInBackground(connector.java:105)
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:292)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
The problem was server-side and was resolved by using appropriate headers.
OkHttp still doesn't seem to work and the function "public static String getDef(String urlInput)" mentioned above works flawlessly.
It seems there's an open bug about this issue:
https://github.com/square/okhttp/issues/1518
They suggest adding android:vmSafeMode="true" to the manifest file.

NetworkOnMainThreadException when I change HTTP to HTTPS in AsyncTask or Thread

I am stuck at this problem. The user inputs their website. It is either http or https, but when they input a https website I get a NetworkOnMainThreadExecption below is my AsyncTask. What am I doing wrong? If I remove the runOnUiThread I get a Only the original thread that created a view hierarchy can touch its views error which I think means that any updated to the UI need to be done in a Thread? So when I put the updates in the Thread I get NetworkOnMainThreadExecption error.
private class runBabyRun extends AsyncTask<Void, Integer, String> {
final TextView temperature = (TextView) findViewById(R.id.mTemp4);
// a few more TextViews here
#Override
protected String doInBackground(Void... params) {
try {
if (httpSelection.equals("http://")) {
HttpClient httpClient = new DefaultHttpClient();
// get url data
HttpPost httppost = new HttpPost(weburi);
HttpResponse response = httpClient.execute(httppost);
HttpEntity entity = response.getEntity();
webs = entity.getContent();
}
if (httpSelection.equals("https://")) {
Log.e("log_tag", "Entered https if statement ");
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient client = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
// get url data
HttpPost httpPost = new HttpPost(weburi);
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
webs = entity.getContent();
}
// convert response to string
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(webs, "iso-8859-1"),
8);
// read one line of code, file is one whole string.
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
//split file into array using space as delimiter
String clientraw = reader.readLine();
String[] parts = clientraw.split(" ");
clientRawData.addAll(Arrays.asList(parts));
//A few more setting up of fields here
// Get Weather Station Title
getSupportActionBar().setTitle(name(parts[32]));
temperature.setText(parts[4] + degrees);
time.setText(parts[29] + ":" + parts[30]);
date.setText(parts[74]);
webs.close();
} catch (Exception e) {
Log.e("log_tag", "Error in displaying textview " + e.toString());
e.printStackTrace();
}
}
});
} catch (Exception e) {
Log.e("log_tag", "Error converting string " + e.toString());
}
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
Toast.makeText(getApplicationContext(), "Error in Connection, please check your URL - " + weburi, Toast.LENGTH_LONG).show();
// setup intent for Settings
Intent intent = new Intent(MainActivity.this, Setting.class);
// Launch the Settings Activity using the intent for result
startActivityForResult(intent, UPDATE_WEBURL);
}
return null;
}
EDIT AFTER COMMENTS BELOW
I have updated my app t have the onPostExecute and it looks like code below but I still get the NetworkOnMainThreadExeption error:
E/log_tag﹕ Error in displaying textview android.os.NetworkOnMainThreadException
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// convert response to string
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(webs, "iso-8859-1"),
8);
// read one line of code, file is one whole string.
try {
//split file into array using space as delimiter
String clientraw = reader.readLine();
String[] parts = clientraw.split(" ");
// Get Weather Station Title
getSupportActionBar().setTitle(name(parts[32]));
temperature.setText(parts[4] + degrees);
//and various other setTexts
windDirection.setText(convertDegrees(parts[3]) + " " + "(" + (parts[3]) + "\u00b0" + ")");
time.setText(parts[29] + ":" + parts[30]);
date.setText(parts[74]);
webs.close();
} catch (Exception e) {
Log.e("log_tag", "Error in displaying textview " + e.toString());
e.printStackTrace();
}
} catch (Exception e) {
Log.e("log_tag", "Error converting string " + e.toString());
}
}
The error log I get is:
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish E/log_tag﹕ Error in displaying textview android.os.NetworkOnMainThreadException
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ android.os.NetworkOnMainThreadException
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:657)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:174)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at java.io.InputStreamReader.read(InputStreamReader.java:231)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at java.io.BufferedReader.fillBuf(BufferedReader.java:145)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at java.io.BufferedReader.readLine(BufferedReader.java:397)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at uk.co.diong.weatherlive_ish.MainActivity$runBabyRun.onPostExecute(MainActivity.java:307)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at uk.co.diong.weatherlive_ish.MainActivity$runBabyRun.onPostExecute(MainActivity.java:227)
03-13 01:39:18.984 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at android.os.AsyncTask.finish(AsyncTask.java:632)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at android.os.Looper.loop(Looper.java:135)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5221)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
03-13 01:39:18.997 5299-5299/uk.co.diong.weatherlive_ish W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
What is causing the NetworkOnMainThreadException is the following line
String clientraw = reader.readLine();
reading from a Stream obtained from a http call, is still a blocking operation and it has to be performed on a background thread

Heavy HTTP requests from Android makes the network disconnected. How to solve this?

I got a very annoying problem now with my android development. I have a list which loading a bunch of content, each is an xml file with different address. Which means I need to sends bunch of http get request to server.
The problem if the request is less than roughly 180 times, I mean continues, very fast http request, the app just works fine. When the amount reach around 180, the connection to internet of the whole device will be lost. That means not only the app won't work, even the default browser or other apps which require internet will also not work.
This will recover after 1 minutes or two. But during this time there are no internet connection.
I do have set permissions in mifest file.
Here is my code for http connection:
public class HTTPService {
private static String response;
public HTTPService() {
response = null;
}
public static String httpGet(String requestURL) {
//Reset response's value to null
response = null;
//DEBUG LOG
Log.i("HTTPService", "Start GET request with URL " + requestURL);
//this function will do http getting action and response checking at same time.
//and assign proper information into the response string.
executeRequest(new HttpGet(requestURL));
Log.i("HTTPService", "GET request return with: " + response);
return response;
}
public static String httpPost(String requestURL, String postString) throws Exception {
//Assemble POST request
HttpPost request = new HttpPost(requestURL);
StringEntity input = new StringEntity(postString);
input.setContentType(CommonCodes.CONTENT_TYPE);
request.setEntity(input);
//DEBUG LOG
Log.i("HTTPService", "Start POST request with URL" + requestURL + ", and post content " + postString);
executeRequest(request);
return response;
}
public static void httpPut(String requestURL, String postString) throws Exception {
//Assemble PUT request
HttpPut request = new HttpPut(requestURL);
StringEntity input = new StringEntity(postString);
input.setContentType(CommonCodes.CONTENT_TYPE);
request.setEntity(input);
//DEBUG LOG
Log.i("HTTPService", "Start PUT request with URL" + requestURL + ", and put content " + postString);
executeRequest(request);
}
public static String httpDelete(String requestURL) {
HttpDelete request = new HttpDelete(requestURL);
//DEBUG LOG
Log.i("HTTPService", "Start DELETE request with URL" + requestURL);
executeRequest(request);
return response;
}
public static void executeRequest(HttpUriRequest request) {
//Check Internet Connection
if (!CheckInternetConnection.checkInternetConnection()) {
responseValidation(CommonCodes.NO_CONNECTION, 0);
}
HttpClient client = sslHttpClient();
HttpResponse httpResponse;
try {
//*********PLACE WHERE ERROR HAPPENS IN ERROR LOG!******//
httpResponse = client.execute(request);
//Check if the request success. If it success, should return 200 as status code.
if (httpResponse.getStatusLine().getStatusCode() != CommonCodes.HTTP_SUCCESS) {
//DEBUG LOG
Log.i("HTTPService", "Request failed with HTTP status code" + httpResponse.getStatusLine().getStatusCode());
//Go through checker
responseValidation(null, httpResponse.getStatusLine().getStatusCode());
}
//When request succeed, retrieve data.
//HttpEntity entity = httpResponse.getEntity();
//Convert stream data into String.
if (!httpResponse.getEntity().equals(null)) {
InputStream instream = httpResponse.getEntity().getContent();
//Convert InputStream to String.
response = convertStreamToString(instream).trim();
//Close stream
instream.close();
httpResponse.getEntity().consumeContent();
}
//Go through checker
responseValidation(response, httpResponse.getStatusLine().getStatusCode());
client.getConnectionManager().shutdown();
} catch (ClientProtocolException e) {
Log.e("HTTPService: ", "HTTP Request With ClientProtocolException Detected");
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
Log.e("HTTPService: ", "HTTP Request With IOException Detected");
client.getConnectionManager().shutdown();
e.printStackTrace();
}
}
public static void responseValidation (String response, int statusCode)
{
//Is this a HTTP Error?
if (statusCode != CommonCodes.HTTP_SUCCESS) {
response = CommonCodes.HTTP_FAIL;
}
//Is the response contains nothing?
else if (response.equals(null) || response.equals("")) {
response = CommonCodes.RESPONSE_EMPTY;
}
//Is there an internet connection?
else if (response.equals(CommonCodes.NO_CONNECTION)){
response = CommonCodes.NO_CONNECTION;
}
}
public static HttpClient sslHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new SSLSocket(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 8080));
registry.register(new Scheme("https", sf, 8443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
The error message I got when the connection lost is this:
05-06 12:13:57.697 28670-28767/com.lai.android E/HTTPService:﹕ HTTP Request With IOException Detected
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ org.apache.http.conn.HttpHostConnectException: Connection to http://test.myworkspace.com:8080 refused
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:183)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at com.lai.android.services.http.HTTPService.executeRequest(HTTPService.java:138)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at com.lai.android.services.http.HTTPService.httpGet(HTTPService.java:73)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at com.lai.android.modules.watchlistgroup.WatchListActivity.getSingleVehicle(WatchListActivity.java:238)
05-06 12:13:57.697 28670-28767/com.lai.android W/System.err﹕ at com.lai.android.modules.watchlistgroup.WatchListActivity$InitWatchListActivity.doInBackground(WatchListActivity.java:144)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at com.lai.android.modules.watchlistgroup.WatchListActivity$InitWatchListActivity.doInBackground(WatchListActivity.java:109)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at java.lang.Thread.run(Thread.java:856)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ Caused by: java.net.ConnectException: failed to connect to /192.168.48.95 (port 8080): connect failed: ENETUNREACH (Network is unreachable)
05-06 12:13:57.705 28670-28767/com.lai.android W/System.err﹕ at libcore.io.IoBridge.connect(IoBridge.java:114)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at java.net.Socket.connect(Socket.java:842)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ ... 17 more
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ Caused by: libcore.io.ErrnoException: connect failed: ENETUNREACH (Network is unreachable)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at libcore.io.Posix.connect(Native Method)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
05-06 12:13:57.713 28670-28767/com.lai.android W/System.err﹕ at libcore.io.IoBridge.connect(IoBridge.java:112)
05-06 12:13:57.721 28670-28767/com.lai.android W/System.err﹕ ... 22 more
Any advice will be welcome! I'm thinking if this is caused by running up of ports. But I don't know how to solve it. Thank you!
Lucky....I solved it.
The problem is I have too many HTTP Clients instance, which used up all ports on the Phone.
Android have a max connection limit, and it takes time to release the ports which are been used. So if the requests are heavy and happens in very short time, the device just won't got enough time to release them.
The solution is instead of using new client every time, use only one client for all request.
Adding this to the code:
private static HttpClient client;
public static synchronized void createHttpClient() {
if(client == null) {
Log.i("HTTPService", "Create Client");
client = sslHttpClient();
}
}
Then call this constructor from beginning of the application.
Then replace everywhere where create new http client with the static client.
Problem solved, I will go for a beer.

Categories

Resources