I need to send asynchronously data to an Api and I am using IntentService.
It freezes when calling con.getResponseCode().
It didn't ALWAYS freeze, at the beginning I have sent requests to the server without problems. At a certain point it started freezing. From then it freezes everytime, like it is waiting for response but it never comes.
This is for android api from 19 and higher (I am actually running on api 24 anyway).
I have used this code in AsyncTask before and it worked (divided in doInBackground() and onPostExecute()). This time I need something that can run in background even when the app is closed so AsyncTask is excluded.
I'm posting the code inside onHandleIntent of MyIntentService class that extends IntentService.
About the Api that I made for this it works fine, I've already tested it.
EDIT: I tried with JobIntentService but it doesn't work anyway. I'm surely missing something but I don't understand what.
String ret = "";
HttpURLConnection con = null;
DbManager db = new DbManager(getApplicationContext());
try{
SharedPreferences pref =
getApplicationContext().getSharedPreferences("MyPref", 0);
String URL_STRING = pref.getString("STORED_URL_FOR_REST_SERVICE",
null) + "/api/values/7";
URL Url = new URL (URL_STRING);
con = (HttpURLConnection) Url.openConnection();
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("json_input", db.getJsonToSend());
con.setRequestMethod("POST");
//con.setDoInput(true);
//con.setDoOutput(true);
con.setUseCaches(false);
int responseCode = con.getResponseCode();
if (responseCode == 200 || responseCode == 201 ) {
BufferedReader br = new BufferedReader(new
InputStreamReader(con.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
ret = sb.toString();
} else {
ret = "ERRORE: " + Integer.toString(con.getResponseCode());
}
}catch(Exception e){
ret = "ERRORE: " + e.getMessage();
}
finally {
if(con != null) {
con.disconnect();
}
}
if(ret.contains("ERRORE")){
Toast.makeText(getApplicationContext(), "Errore nell'invio dei
dati\nNuovo tentativo a breve", Toast.LENGTH_SHORT).show();
}else{
Gson gson = null;
Rest1 r2 = null;
try {
gson = new Gson();
r2 = gson.fromJson(ret, Rest1.class);
db = new DbManager(getApplicationContext());
}catch(Exception e){
Toast.makeText(this, e.getMessage(),
Toast.LENGTH_SHORT).show();
}
try {
db.setRowToSent(r2.getResult().split("#"));
}catch(Exception e){
Toast.makeText(this, e.getMessage(),
Toast.LENGTH_SHORT).show();
}
if (r2.getMessage().equals("OK")) {
} else if (r2.getMessage().equals("KO")) {
Toast.makeText(getApplicationContext(), "Errore nell'invio dei
dati\nNuovo tentativo a breve",
Toast.LENGTH_SHORT).show();
}
}
Related
I have a problem that I haven't solved yet and I need help.
When internet is slow application crashes. how can can I check connection timeout in asyntask.
I made an app that sometimes connect to web service to get data and i do that using async task
I want to make alert dialog on connection timeout when user can choose whether they want to retry or cancel, if they choose retry it will try to connect again
public class login extends AsyncTask<Void,Void,Void> {
InputStream ins;
String status, result, s = null, data = "",js;
int ss;
int responseCode;
#Override
protected void onPreExecute() {
super.onPreExecute();
pdlg.setTitle("Checking");
pdlg.setMessage("Please wait");
pdlg.setCancelable(false);
pdlg.show();
}
#Override
protected Void doInBackground(Void... params) {
StringBuilder sb = new StringBuilder();
ArrayList al;
try {
URL url = new URL("http://....login.php");
String param = "username=" + uname + "&password=" + pass;
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setConnectTimeout(15000);
connection.setReadTimeout(15000);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
bw.write(param);
bw.flush();
bw.close();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
}
data = sb.toString();
JSONObject json = new JSONObject(data);
status=json.getString("Status");//{"Login Status":"Success","Receipt Details":"No data available"}
// js=json.getString("Login");//{"Login":"Failed"}
} catch (MalformedURLException e) {
Log.i("MalformedURLException", e.getMessage());
} catch (IOException e) {
Log.i("IOException", e.getMessage());
} catch (JSONException e) {
Log.i("JSONException", e.getMessage());
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
String status1=status.trim();
if (status1.equals("Success")) {
Toast.makeText(getApplicationContext(), "Login Succes !!", Toast.LENGTH_SHORT).show();
Intent i = new Intent(Login.this, Home.class);
startActivity(i);
finish();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("first_time", false);
editor.putString("userrname", uname);
editor.putString("password",pass);
editor.apply();
Toast.makeText(getApplicationContext(),"welcome : "+uname,Toast.LENGTH_LONG).show();
}
else {
Toast t=Toast.makeText(Login.this, "Username or Password is Incorrect", Toast.LENGTH_LONG);
t.setGravity(Gravity.BOTTOM,0,0);
t.show();
}
pdlg.dismiss();
}
}
You can use getErrorStream() ,
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream inp;
// if some error in connection
inp = connection.getErrorStream();
check this answer for more details..
according to the doc it returns
an error stream if any, null if there have been no errors, the
connection is not connected or the
server sent no useful data
.
use this two catch blocks to handle ConnectionTimeOut and socketTimeOut Exceptions
catch (SocketTimeoutException bug) {
Toast.makeText(getApplicationContext(), "Socket Timeout", Toast.LENGTH_LONG).show();
}
catch (ConnectTimeoutException bug) {
Toast.makeText(getApplicationContext(), "Connection Timeout", Toast.LENGTH_LONG).show();
}
For Connection time out add SocketTimeoutException in your catch block and its crashing because without null checking, you are trying to trim the string in onPostExecute
You should do like this, and check before using status
if(TextUtil.isEmpty(status)) {
pdlg.dismiss();
// We are getting empty response
return;
}
String status1=status.trim();
You can catch the Connection timeout exception in your code and then set the status according to your requirement and check for that status in onPostExecute to show the alert Dialog
try {
URL url = new URL("http://....login.php");
String param = "username=" + uname + "&password=" + pass;
// Your URL connection code here
catch (ConnectTimeoutException e) {
Log.e(TAG, "Timeout", e);
status="timeout"
} catch (SocketTimeoutException e) {
Log.e(TAG, " Socket timeout", e);
status="timeout"
}
in onPostExecute
if (status.equals("timeout")) {
// Show Alert Dialog.
}
What you are trying to do is previously done in some great networking lib. So I urge you to use one of the widley used network lib.
Volley.
Or if you want to understand you can just check the response status(or status code should be 408. I guess for connection time out) if it will return "connection time out" then you can call your code to the http client again to perform your task, you can also add a retry count to try for 2-3 times and then give up and send response to onpostexecute method.
Hope this helps.
The docs say AsyncTask is designed to handle short operations(few seconds maximum) and states that Java classes like FutureTask are better for operations that last long. So I tried to send my location updates to the server using FutureTask but I am getting NetworkOnMainThreadException. I don't want to use AsyncTask because I wanted to keep the http connection open until the updates are cancelled. Here is my code:
SendLocation updates = new SendLocation(idt, String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
FutureTask ft = new FutureTask<String>(updates);
boolean b = ft.cancel(false);
ft.run();
class SendLocation implements Callable<String> {
String t, la, lo;
public SendLocation(String a, String b, String c){
this.t = a;
this.la = b;
this.lo = c;
}
public String call() {
sendUpdates(token, la, lo);
return "Task Done";
}
public void sendUpdates(String a, String b, String c){
HttpURLConnection urlConn = null;
try {
try {
URL url;
//HttpURLConnection urlConn;
url = new URL(remote + "driver.php");
urlConn = (HttpURLConnection) url.openConnection();
System.setProperty("http.keepAlive", "true");
//urlConn.setDoInput(true); //this is for get request
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setRequestProperty("Content-Type", "application/json");
urlConn.setRequestProperty("Accept", "application/json");
urlConn.setRequestMethod("POST");
urlConn.connect();
try {
//Create JSONObject here
JSONObject json = new JSONObject();
json.put("drt", a);
json.put("drlat", b);
json.put("drlon", c);
String postData = json.toString();
// Send POST output.
OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
os.write(postData);
Log.i("NOTIFICATION", "Data Sent");
os.flush();
os.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String msg = "";
String line = "";
while ((line = reader.readLine()) != null) {
msg += line;
}
Log.i("msg=", "" + msg);
} catch (JSONException jsonex) {
jsonex.printStackTrace();
Log.e("jsnExce", jsonex.toString());
}
} catch (MalformedURLException muex) {
// TODO Auto-generated catch block
muex.printStackTrace();
} catch (IOException ioex) {
ioex.printStackTrace();
try { //if there is IOException clean the connection and clear it for reuse(works if the stream is not too long)
int respCode = urlConn.getResponseCode();
InputStream es = urlConn.getErrorStream();
byte[] buffer = null;
int ret = 0;
// read the response body
while ((ret = es.read(buffer)) > 0) {
Log.e("streamingError", String.valueOf(respCode) + String.valueOf(ret));
}
// close the errorstream
es.close();
} catch(IOException ex) {
// deal with the exception
ex.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
Log.e("ERROR", "There is error in this code " + String.valueOf(e));
}
}
}
Doesn't it get executed in a worker thread? If the answer is no why does the docs say that it is an alternative to AsyncTask?
Your code must not be in the void run() method. This is where the asynchronous code is ran.
all of a sudden my mobile device can't connect to the local server anymore. async tasks are not executed and i just can't figure out why. slowly i'm getting really desperate because in my opinion i didn't change anything to cause this.
as an example, this is a background task which is not working
public class Login extends AsyncTask<String, Void, String>{
private String loginUrl = "http://...";
private int loginSuccess = 0;
public String getToken(String fromJson) throws JSONException {
JSONObject json = new JSONObject(fromJson);
if(json.has("api_authtoken")) {
loginSuccess = 1;
String appToken = json.getString("api_authtoken");
return appToken;
}
else {
return json.toString();
}
}
public String doInBackground(String... arg0) {
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String authToken;
try {
// get logged in to get the api_authtoken
String email = (String) arg0[0];
String password = (String) arg0[1];
URL url = new URL(loginUrl);
// Create the request and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
//put values of edittexts into json-Object
JSONObject data = new JSONObject();
try {
data.put("email", email);
data.put("password", password);
} catch(JSONException e) {
Log.e("EXCEPTION", "unexpected JSON exception", e);
e.printStackTrace();
}
urlConnection.connect();
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(data.toString());
wr.flush();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
//read server response
while((line = reader.readLine()) != null) {
sb.append(line);
}
//receive server "answer"
try {
return getToken(sb.toString());
}catch(JSONException e) {
Log.e("LOG", "unexpected JSON exception", e);
e.printStackTrace();
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("MainActivity", "Error closing stream", e);
}
}
}
//return sb.toString();
return null;
}
catch(IOException e) {
Log.e("LoginTask", "Error ", e);
// If the code didn't successfully get the data, there's no point in attempting
// to parse it.
//forecastJsonStr = null;
return null;
}
}
public void onPostExecute(String result) {
super.onPostExecute(result);
//Log.v("RESULT", result);
if(result == null) {
CharSequence text = "no internet connection";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
if(loginSuccess == 0) {
// if the request wasn't successful
// give user a message via toast
CharSequence text = "wrong password or user. please try again";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
else {
// save token in shared preferences
SharedPreferences tokenPref = getSharedPreferences(getString(R.string.preference_token), Context.MODE_PRIVATE);
SharedPreferences.Editor editorToken = tokenPref.edit();
editorToken.putString(getString(R.string.saved_auth_token), result);
editorToken.commit();
//save login status = 1 in shared preferences
SharedPreferences loginPref = getSharedPreferences(getString(R.string.preference_logged_in), Context.MODE_PRIVATE);
SharedPreferences.Editor editorLogin = loginPref.edit();
editorLogin.putString(getString(R.string.saved_login), "1");
editorLogin.commit();
Intent mapsIntent = new Intent(getApplicationContext(), MapsActivity.class);
startActivity(mapsIntent);
}
}
}
HttpClient is not supported any more in sdk 23. You have to use URLConnection or downgrade to sdk 22 (compile 'com.android.support:appcompat-v7:22.2.0')
If you need sdk 23, add this to your gradle:
android {
useLibrary 'org.apache.http.legacy'
}
HttpClient won't import in Android Studio
You should think about using a HTTP library, there is a bunch of them on internet, some are really easy to use, optimize and errorless.
For example, Volley (made by Google, I really like this one), okHttp or Picasso (for image).
You should take a look at this.
If you want to send (output), for example with POST or PUT requests you need to use this :-
urlConnection.setDoOutput(true);
In your code :-
public class Login extends AsyncTask<String, Void, String>{
private String loginUrl = "http://...";
private int loginSuccess = 0;
public String getToken(String fromJson) throws JSONException {
JSONObject json = new JSONObject(fromJson);
if(json.has("api_authtoken")) {
loginSuccess = 1;
String appToken = json.getString("api_authtoken");
return appToken;
}
else {
return json.toString();
}
}
public String doInBackground(String... arg0) {
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String authToken;
try {
// get logged in to get the api_authtoken
String email = (String) arg0[0];
String password = (String) arg0[1];
URL url = new URL(loginUrl);
// Create the request and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setDoOutput(true); // HERE
//put values of edittexts into json-Object
JSONObject data = new JSONObject();
try {
data.put("email", email);
data.put("password", password);
} catch(JSONException e) {
Log.e("EXCEPTION", "unexpected JSON exception", e);
e.printStackTrace();
}
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(data.toString());
wr.flush();
urlConnection.connect();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
//read server response
while((line = reader.readLine()) != null) {
sb.append(line);
}
//receive server "answer"
try {
return getToken(sb.toString());
}catch(JSONException e) {
Log.e("LOG", "unexpected JSON exception", e);
e.printStackTrace();
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("MainActivity", "Error closing stream", e);
}
}
}
//return sb.toString();
return null;
}
catch(IOException e) {
Log.e("LoginTask", "Error ", e);
// If the code didn't successfully get the data, there's no point in attempting
// to parse it.
//forecastJsonStr = null;
return null;
}
}
public void onPostExecute(String result) {
super.onPostExecute(result);
//Log.v("RESULT", result);
if(result == null) {
CharSequence text = "no internet connection";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
if(loginSuccess == 0) {
// if the request wasn't successful
// give user a message via toast
CharSequence text = "wrong password or user. please try again";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(MainActivity.this, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
else {
// save token in shared preferences
SharedPreferences tokenPref = getSharedPreferences(getString(R.string.preference_token), Context.MODE_PRIVATE);
SharedPreferences.Editor editorToken = tokenPref.edit();
editorToken.putString(getString(R.string.saved_auth_token), result);
editorToken.commit();
//save login status = 1 in shared preferences
SharedPreferences loginPref = getSharedPreferences(getString(R.string.preference_logged_in), Context.MODE_PRIVATE);
SharedPreferences.Editor editorLogin = loginPref.edit();
editorLogin.putString(getString(R.string.saved_login), "1");
editorLogin.commit();
Intent mapsIntent = new Intent(getApplicationContext(), MapsActivity.class);
startActivity(mapsIntent);
}
}
}
I am getting following error in con.getResponseCode()
java.net.SocketTimeoutException: failed to connect to example.com (port 80) after 3000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:223)
at libcore.io.IoBridge.connect(IoBridge.java:127)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:475)
at java.net.Socket.connect(Socket.java:861)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:152)
at com.android.okhttp.Connection.connect(Connection.java:101)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:503)
First time when it gets called it works perfectly.
But it stops working after it and it may start working randomly after some time.
public class HTTPLoader {
public static String loadContentFromURLGET(String urlString,List<String[]> getVars,Context context){
int retry = 0;
HttpURLConnection con=null;
BufferedReader in = null;
StringBuffer response=null;
if (!isConnectingToInternet(context)){
return "{'error':'No Internet connection!'}";
}
while (retry++<=RETRY_CNT) {
try {
String urlParameters = "";
for (String[] var : getVars) {
urlParameters += var[0] + "=" + URLEncoder.encode(var[1], "UTF-8") + "&";
}
if (urlParameters.length() > 1) {
urlParameters = urlParameters.substring(0, urlParameters.length() - 1);
}
if (urlString.charAt(urlString.length() - 1) != '?') {
urlString += "&";
}
URL url = new URL(urlString + urlParameters);
con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(3000);
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setDoInput(true);
con.setDoOutput(true);
int responseCode = con.getResponseCode();
in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
retry = RETRY_CNT+1;
break;
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}finally {
if (in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (con!=null) {
con.disconnect();
}
in = null;
con = null;
}
}
if (response!=null)
return new String(response);
return "{'error':'No Internet connection!'}";
}
}
This loadContentFromURLGET is getting called from IntentService
public class ChatUtil extends IntentService{
protected String loadAllChats(String date){
String response = "";
try {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String email = sharedPreferences.getString(QuickstartPreferences.EMAIL, "");
List<String[]> postVars = new ArrayList<>();
postVars.add(new String[]{"getconversation", "yes"});
postVars.add(new String[]{"user_id", email});
postVars.add(new String[]{"last_date", date});
String urlString = getString(R.string.get_conversation_url);
response = HTTPLoader.loadContentFromURLGET(urlString, postVars,getApplicationContext());
Log.i(TAG, response.toString());
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.has("error")) {
//Toast.makeText(getApplicationContext(), jsonObject.getString("error"), Toast.LENGTH_SHORT).show();
return jsonObject.getString("error");
}
}catch (JSONException e) {
}
}
protected void onHandleIntent(Intent intent) {
String task = intent.getStringExtra(QuickstartPreferences.CURRENT_TASK);
Intent nintent;
String date = "";
String[] arr3 = new NewsDBUtil(getApplicationContext()).getLastChatEntry(null);
if (arr3!=null)
date = arr3[1];
loadAllChats(date);
nintent = new Intent(QuickstartPreferences.LOADING_ALL_CHAT);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(nintent);
}
}
Tried closing and disconnecting stream in finally block.
But no Success.
you can put con.getResponseCode(); between try ...catch block if it throw SocketTimeoutException Exception make another try , but make sure you extend your timeout
if (responseCode != 200) {
....
...
} catch (final java.net.SocketTimeoutException e) {
// connection timed out...let's try again
}
may this help
Without specific ContentLength via setFixedLengthStreamingMode
I found some devices generated incomplete http request
cause the server has to wait until either server or client timed out
you can use wireshark to analyze the problem
I am using the following code to request a response from a webserver. The server sends a malformed response without headers which causes a ClientProtocolException. I have tried to use inspectors but they are not called before the exception is fired. I cannot change the server (it is within an embedded device, ALFA router R36).
Any suggestions to deal with this problem (btw: the code works perfect if the server response is well-formed)
Thanks in advance, Ton
class httpRequestTask extends AsyncTask <Integer, Integer, Integer> {
StringBuffer respTxt = new StringBuffer("");
int reqCode = 0;
protected Integer doInBackground(Integer... requestCode) {
Integer reqStatus = 0;
String url = "http://192.168.2.1/";
String authString = ("admin:admin");
switch( reqCode = requestCode[0].intValue()){
case Constants.HTTP_GET_STATUS_INFO: url += "/adm/status_info.asp"; break;
case Constants.HTTP_SCAN: url += "/goform/getUsbStaBSSIDListForm"; break;
}
try {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
HttpResponse response;
request.setURI( new URI( url));
request.addHeader("Authorization", "Basic " + Base64.encodeToString(authString.getBytes(),Base64.NO_WRAP));
response = client.execute(request);
reqStatus = response.getStatusLine().getStatusCode();
String line;
BufferedReader in = new BufferedReader( new InputStreamReader(response.getEntity().getContent()));
while((line = in.readLine()) != null) respTxt.append(line);
} catch ( ClientProtocolException e){
Log.e("ALFA", "HTTPReq:ClientProtocolException " + e.toString());
} catch ( IOException e){
Log.e("ALFA", "HTTPReq:IOException " + e.toString());
} catch ( Exception e){
Log.e("ALFA", "HTTPReq:Exception " + e.toString());
}
return reqStatus;
}
protected void onPostExecute(Integer reqStatus) {
Intent intent = new Intent(Constants.HTTP_RESPONSE);
intent.putExtra( "reqCode", reqCode);
intent.putExtra( "reqStatus", reqStatus);
intent.putExtra( "rspTxt", respTxt.toString());
getBaseContext().sendBroadcast(intent);
}
}
Looking further to find a solution to the problem I found a suggestion to use a socket to request the server. I used Fiddler in combination with a browser on my PC to examine the data send to and received from the buggy server and read an article on Wikipedia, explaining the HTTP protocol. With that info and by using a Socket, I wrote a very basic httpRequestHandler than deals with the miss formed response from the buggy web server.
class httpSocketRequest extends AsyncTask<Integer, Integer, Integer> {
StringBuffer respTxt = new StringBuffer("");
int reqCode = 0;
int reqStatus = 0;
protected Integer doInBackground(Integer... requestCode) {
String ip = "192.168.2.1";
String path = "";
String authString = ("admin:admin");
Socket socket = null;
switch( reqCode = requestCode[0].intValue()){
case Constants.HTTP_GET_STATUS_INFO: path = "adm/status_info.asp"; break;
case Constants.HTTP_SCAN: path = "goform/getUsbStaBSSIDListForm"; break;
}
try {
socket = new Socket( ip, 80);
PrintWriter out = new PrintWriter( socket.getOutputStream());
out.println( "GET http://" + ip + "/" + path + " HTTP/1.0");
out.println( "Authorization: Basic " + Base64.encodeToString(authString.getBytes(),Base64.NO_WRAP));
out.println( "");
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
int lineCnt = 0;
while((line = in.readLine()) != null){
if( lineCnt >= 0){
lineCnt++;
if(lineCnt == 1){ // first line should start with "HTTP/1.x " followed by a 3 digit status
if( line.length() > 12 && line.substring(0, 6).equals("HTTP/1")){
int p = line.indexOf(" ");
reqStatus = Integer.parseInt(line.substring(p+1, p+4));
continue;
} else { // not a well formed response
lineCnt = -1; // just put everything into respTxt
reqStatus = 200; // and assume everything went OK
}
} else if( lineCnt > 1){ // process rest of headers
if( line.length() == 0){
lineCnt = -1; // done with headers
} else {
// TODO insert code to process other headers
}
continue;
}
}
respTxt.append(line + "\n");
}
} catch (Exception e) {
Log.e("ALFA", "HTTPReq:Exception " + e.toString());
} finally {
try {
if( socket != null) socket.close();
} catch (IOException e) {
Log.e("ALFA", "HTTPReq:Exception closing socket" + e.toString());
}
}
return reqStatus;
}
protected void onPostExecute(Integer reqStatus) {
Intent intent = new Intent(Constants.HTTP_RESPONSE);
intent.putExtra( "reqCode", reqCode);
intent.putExtra( "reqStatus", reqStatus);
intent.putExtra( "rspTxt", respTxt.toString());
getBaseContext().sendBroadcast(intent);
}
}