I am using an asynchronous post method to post some data to the server. The post is working fine, but if the server is down or unresponsive then I am getting a force close in the application.
How should I implement a timeout to the post request?
This is the class which is asynchronously posting to a particular url:
//===================================================================================================================================
//sending EmailAddress and Password to server
//===================================================================================================================================
private class MyAsyncTask extends AsyncTask<String, Integer, Double>{
#Override
protected Double doInBackground(String... params) {
// TODO Auto-generated method stub
postData(params[0],params[1]);
return null;
}
protected void onPostExecute(Double result){
if(responseBody.contains("TRUE"))
{
String raw=responseBody;
raw = raw.substring(0, raw.lastIndexOf("<"));
raw = raw.substring(raw.lastIndexOf(">") + 1, raw.length());
String [] contents = raw.split(",");
//extracting user name and user id from response
String user_name=contents[1];
String student_code=contents[2];
//save user name and user id in preference
saveInPreference("user_name",user_name);
saveInPreference("student_code",student_code);
//login is successful, going to next activity
Intent intent = new Intent(LoginActivity.this, TakeTestActivity.class);
//hiding progress bar
progress.dismiss();
finish();
LoginActivity.this.startActivity(intent);
}
else
{
//hiding progress bar
progress.dismiss();
create_alert("Attention!", "Please provide valid userid and password");
}
}
protected void onProgressUpdate(Integer... progress){
}
public void postData(String emailId,String passwrd) {
**//EDIT START**
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient httpclient = new DefaultHttpClient(httpParams);
**//EDIT END**
// Create a new HttpClient and Post Header
//HttpClient httpclient = new DefaultHttpClient();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(LoginActivity.this);
final String url_first = preferences.getString("URLFirstPart","");
HttpPost httppost = new HttpPost(url_first+"ValidateLogin");
try {
// Data that I am sending
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("EmailId", emailId));
nameValuePairs.add(new BasicNameValuePair("Password", passwrd));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
**//EDIT START**
try
{
// Execute HTTP Post Request
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
responseBody = EntityUtils.toString(response.getEntity());
}
catch (SocketTimeoutException ex)
{
// Do something specific for SocketTimeoutException.
}
**//EDIT END**
//Log.d("result", responseBody);
}
catch (Throwable t ) {
}
}
}
//===================================================================================================================================
//END sending EmailAddress and Password to server
//===================================================================================================================================
This is how I am calling the class to execute the post request:
//sending request for login
new MyAsyncTask().execute(txtUsername.getText().toString(),txtPassword.getText().toString());
What should I do to implement a connection timeout after a particular time if the server does not respond or is not available?
Edited:
How do I notify the user using an alert that the connection has timed out? Where should I put the alert and during which condition?
Thanks in advance!
You can try this, I've set 10 sec. here...
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient client = new DefaultHttpClient(httpParams);
Related
How to send value to php page using Asynchronous with HttpRequest and get a response, then do something with it using OnPostExcute for example.
Java :
private class MyAsyncTask extends AsyncTask<String, Integer, Double>{
#Override
protected Double doInBackground(String... params) {
// TODO Auto-generated method stub
postData(params[0]);
return null;
}
protected void onPostExecute(Double result){
pb.setVisibility(View.GONE);
// Do something with the response here
// ....
}
public void postData(String valueIWantToSend) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("__url_to_file.php");
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("myHttpData", valueIWantToSend));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
}
}
PHP :
<?php
// return the value back to the app
echo $_POST["myHttpData"];
?>
private class MyAsyncTask extends AsyncTask<String, HttpResponse, HttpResponse>{
#Override
protected HttpResponse doInBackground(String... params) {
// TODO Auto-generated method stub
return postData(params[0]);
}
protected void onPostExecute(HttpResponse result){
View pb;
pb.setVisibility(View.GONE);
HttpEntity entity = result.getEntity();
String responseString = EntityUtils.toString(entity, "UTF-8");
Toast.makeText(mContext, responseString, Toast.LENGTH_LONG).show();
}
#SuppressWarnings("unchecked")
public HttpResponse postData(String valueIWantToSend) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("__url_to_file.php");
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("myHttpData", valueIWantToSend));
httppost.setEntity(new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
return response;
}
}
You could do something with the above. That would certainly pass the HttpResponse to the onPostExecute method and allow you to do something with it.
I'd take a look at this line, though:
httppost.setEntity(new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) nameValuePairs));
As it didn't seem right to me. I had to add the cast to make the compiler happy. That may not be the desired result (but the point wast to get the ASyncTask to allow for processing the HttpResponse).
I want to know that if a doInBackground method of a AsyncTask calls a method, for example XYZ(), Is that method also executed asynchronously?
Can we make changes to the UI in XYZ() in such a situation? Will it make the UI unresponsive?
I have a method call in doInBackground which is network intensive and requires to download an image from the web. The UI becomes unresponsive as soon as the call to that method is made. Why?
protected String[] doInBackground(String... params)
{
String[] response = new String[2];
Log.v("Background", "I am in background!");
String url = params[0];
String VoiceInput = params[1];
IsCalledOnVoiceInput = VoiceInput;
Log.v(url,url);
HttpPost httppost = new HttpPost(url);
try
{
HttpParams p = new BasicHttpParams();
HttpClient httpclient = new DefaultHttpClient(p);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
responseBody = httpclient.execute(httppost,
responseHandler);
Log.v("Thread", responseBody);
//Getting background image URL
JSONObject reader = new JSONObject(responseBody);
JSONObject coords = reader.getJSONObject("coord");
loc_latitude = coords.getString("lat");
loc_longitude = coords.getString("lon");
String imageURL="";
/////////////////////////////////////////////////////////////////////////////////
try
{
imageURL = getRandomImageURL(loc_latitude,loc_longitude);
Log.v("Image URL as recieved from getRandomImageURL", imageURL);
//Trying to convert Image from the above URL, get it and theh convert it to String
URL urlOfTheImage = new URL(imageURL);
bmp = BitmapFactory.decodeStream(urlOfTheImage.openConnection().getInputStream());
//Image successfully converted to string, ready to pass as a parameter!
response[0] = "";
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(),"There seems to be a problem with the application. Please try again later.", Toast.LENGTH_LONG).show();
}
Log.v("URL of Random Image",imageURL);
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
response[1] = responseBody;
return response;
}
The method getRandomImageURL and all that code in the try block is network intensive. I can also provide its code.
The code executing in the background is run in a separate thread. Anything it does, including calling other methods, happens in that thread. Since this is not the UI thread, it's not valid to make UI calls. You have to post messages to the UI thread.
Yes, whatever you call within doInBackgroud will run asynchronously. And no you shoudn't update UI from background thread for that you have CallBackDefined(onPostExecute). Or if UI update is require you can use runOnUIThread(...) API
You can make changes to the UI only from the UI thread. In general the doInBackground() is for lengthy operations that do not update the UI or access the UI toolkit. You can periodically publish changes in state that need to be reflected in the UI (eg progress bar showing status of a download operation) by calling publishProgress().
Set time out like this...
HttpPost httppost = new HttpPost(url);
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(httppost);
i'am tring to login into website with post method ... to right here the code is code but the response always give me 200 ... i want to know if i logged in successfully with the right username and password or not !!! ... also if i removed permitAll() it give me networkonmainthreadexception
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#SuppressLint("NewApi")
private void sendPost() {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://svuonline.org/isis/login.php?");
String user=username.getText().toString();
String pass=password.getText().toString();
String fpage="/isis/index.php";
/* if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}*/
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("user_name", user));
nameValuePairs.add(new BasicNameValuePair("user_pass", pass));
nameValuePairs.add(new BasicNameValuePair("user_otp", null));
nameValuePairs.add(new BasicNameValuePair("from_page", fpage));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
String Rcode=response.toString();
Toast.makeText(getBaseContext(), Rcode+"", Toast.LENGTH_LONG).show();
} catch (ClientProtocolException e) {
Toast.makeText(getBaseContext(), e+"", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getBaseContext(), e+"", Toast.LENGTH_LONG).show();
}
}
You can read about it here:
HTTP response
10.2.1 200 OK
The request has succeeded.
I want to know why does this code not execute? I'm trying to send my data from my device via POST method but there is no error. The app just finishes by itself on my device by communicating "My app was stopped.:
Here is execution:
KlientNameValue kn = new KlientNameValue(getApplicationContext());
kn.new MyAsyncTask().execute(zam.klient.getNazwa(),zam.klient.getNip(),zam.klient.getAdres());
And here is code:
public class KlientNameValue {
List<NameValuePair> KlientNameValuePairs = new ArrayList<NameValuePair>();
Context context;
public KlientNameValue(Context context) {
super();
this.context=context;
}
public class MyAsyncTask extends AsyncTask<String, Void, Void> {
#Override protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
postData(params[0], params[1], params[2]);
return null;
}
#Override
protected void onPostExecute(Void result) {
Toast.makeText(context , "Zlecenie zostało wysłane",
Toast.LENGTH_LONG).show();
}
void postData(String nazwa, String nip, String adres) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("here is my default link :)");
try { // Add your data
KlientNameValuePairs = new ArrayList<NameValuePair>();
KlientNameValuePairs.add(new BasicNameValuePair("Kli_imie", nazwa));
KlientNameValuePairs.add(new BasicNameValuePair("Kli_adres", adres));
KlientNameValuePairs.add(new BasicNameValuePair( "Kli_nr_telefonu",
nip));
httppost.setEntity(new UrlEncodedFormEntity( KlientNameValuePairs));
HttpResponse response = httpclient.execute(httppost);
//httppost.setEntity(new UrlEncodedFormEntity(
// ZamowienieNameValuePairs)); // HttpResponse response1 =
} catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace(); }
}
}
}
Error:
02-15 17:45:24.695: E/AndroidRuntime(21890): at android.widget.Toast.<init>(Toast.java:94)
02-15 17:47:19.343: W/SingleClientConnManager(22288): Invalid use of SingleClientConnManager: connection still allocated.
02-15 17:47:19.343: W/SingleClientConnManager(22288): Make sure to release the connection before allocating another one.
Invalid use of SingleClientConnManager: connection still allocated.
You are executing the http request two times that is completely wrong before you consume it. So remove the second httpclient.execute(httppost); because you have already execute this http request.
and call this
httpResponse.getEntity().consumeContent();
Above method is called to indicate that the content of this entity is no longer required. All entity implementations are expected to release all allocated resources as a result of this method invocation
public static DefaultHttpClient getThreadSafeClient() {
DefaultHttpClient client = new DefaultHttpClient();
ClientConnectionManager mgr = client.getConnectionManager();
HttpParams params = client.getParams();
client = new DefaultHttpClient(
new ThreadSafeClientConnManager(params,
mgr.getSchemeRegistry()), params);
return client;
}
use this code so that your exception of free resource and allocate or being used will not come
This exception can happen when two or more threads interact with a single org.apache.http.impl.client.DefaultHttpClient
or simply give new object to each request when and where ever you are calling you get or post http client request to interact with server to fetch the data or download the large file
like
String post_url="http://www.google.com";
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpost = new HttpPost(Post_url);
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");
HttpResponse httpResponse = client.execute(httpost);
String response= EntityUtils.toString(httpResponse.getEntity());
as you like in code to retrieve the response
I have to do a http post request to a web-service for authenticating the user with username and password. The Web-service guy gave me following information to construct HTTP Post request.
POST /login/dologin HTTP/1.1
Host: webservice.companyname.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 48
id=username&num=password&remember=on&output=xml
The XML Response that i will be getting is
<?xml version="1.0" encoding="ISO-8859-1"?>
<login>
<message><![CDATA[]]></message>
<status><![CDATA[true]]></status>
<Rlo><![CDATA[Username]]></Rlo>
<Rsc><![CDATA[9L99PK1KGKSkfMbcsxvkF0S0UoldJ0SU]]></Rsc>
<Rm><![CDATA[b59031b85bb127661105765722cd3531==AO1YjN5QDM5ITM]]></Rm>
<Rl><![CDATA[username#company.com]]></Rl>
<uid><![CDATA[3539145]]></uid>
<Rmu><![CDATA[f8e8917f7964d4cc7c4c4226f060e3ea]]></Rmu>
</login>
This is what i am doing HttpPost postRequest = new HttpPost(urlString); How do i construct the rest of the parameters?
Here's an example previously found at androidsnippets.com (the site is currently not maintained anymore).
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
So, you can add your parameters as BasicNameValuePair.
An alternative is to use (Http)URLConnection. See also Using java.net.URLConnection to fire and handle HTTP requests. This is actually the preferred method in newer Android versions (Gingerbread+). See also this blog, this developer doc and Android's HttpURLConnection javadoc.
to #BalusC answer I would add how to convert the response in a String:
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String result = RestClient.convertStreamToString(instream);
Log.i("Read from server", result);
}
Here is an example of convertStramToString.
Please consider using HttpPost. Adopt from this: http://www.javaworld.com/javatips/jw-javatip34.html
URLConnection connection = new URL("http://webservice.companyname.com/login/dologin").openConnection();
// Http Method becomes POST
connection.setDoOutput(true);
// Encode according to application/x-www-form-urlencoded specification
String content =
"id=" + URLEncoder.encode ("username") +
"&num=" + URLEncoder.encode ("password") +
"&remember=" + URLEncoder.encode ("on") +
"&output=" + URLEncoder.encode ("xml");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// Try this should be the length of you content.
// it is not neccessary equal to 48.
// content.getBytes().length is not neccessarily equal to content.length() if the String contains non ASCII characters.
connection.setRequestProperty("Content-Length", content.getBytes().length);
// Write body
OutputStream output = connection.getOutputStream();
output.write(content.getBytes());
output.close();
You will need to catch the exception yourself.
I'd rather recommend you to use Volley to make GET, PUT, POST... requests.
First, add dependency in your gradle file.
compile 'com.he5ed.lib:volley:android-cts-5.1_r4'
Now, use this code snippet to make requests.
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
StringRequest postRequest = new StringRequest( com.android.volley.Request.Method.POST, mURL,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
Log.d("Response", response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", error.toString());
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
//add your parameters here as key-value pairs
params.put("username", username);
params.put("password", password);
return params;
}
};
queue.add(postRequest);
Try HttpClient for Java:
http://hc.apache.org/httpclient-3.x/
You can reuse the implementation I added to ACRA:
http://code.google.com/p/acra/source/browse/tags/REL-3_1_0/CrashReport/src/org/acra/HttpUtils.java?r=236
(See the doPost(Map, Url) method, working over http and https even with self signed certs)
I used the following code to send HTTP POST from my android client app to C# desktop app on my server:
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
I worked on reading the request from a C# app on my server (something like a web server little application).
I managed to read request posted data using the following code:
server = new HttpListener();
server.Prefixes.Add("http://*:50000/");
server.Start();
HttpListenerContext context = server.GetContext();
HttpListenerContext context = obj as HttpListenerContext;
HttpListenerRequest request = context.Request;
StreamReader sr = new StreamReader(request.InputStream);
string str = sr.ReadToEnd();
HTTP request POST in java does not dump the answer?
public class HttpClientExample
{
private final String USER_AGENT = "Mozilla/5.0";
public static void main(String[] args) throws Exception
{
HttpClientExample http = new HttpClientExample();
System.out.println("\nTesting 1 - Send Http POST request");
http.sendPost();
}
// HTTP POST request
private void sendPost() throws Exception {
String url = "http://www.wmtechnology.org/Consultar-RUC/index.jsp";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
// add header
post.setHeader("User-Agent", USER_AGENT);
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("accion", "busqueda"));
urlParameters.add(new BasicNameValuePair("modo", "1"));
urlParameters.add(new BasicNameValuePair("nruc", "10469415177"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + post.getEntity());
System.out.println("Response Code : " +response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(new
InputStreamReader(response.getEntity().getContent()));
StringBuilder result = new StringBuilder();
String line = "";
while ((line = rd.readLine()) != null)
{
result.append(line);
System.out.println(line);
}
}
}
This is the web: http://www.wmtechnology.org/Consultar-RUC/index.jsp,from you can consult Ruc without captcha. Your opinions are welcome!