I have an HttpPost which sends data to a server to be stored on a database. When that data is successfully stored I get a response in my LogCat that says "message has been saved successfully" (this response was defined in my PHP code). I am happy with that, but I am trying to get that same response to be displayed in a Toast. Here is my code:
String myBreadfromr, myBreadtor;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Bundle myBasket = getIntent().getExtras();
myBreadfromr = myBasket.getString("keyfromcellr");
myBreadtor = myBasket.getString("keytocellr");
new SendData().execute("");
}
public class SendData extends AsyncTask<String, Integer, Void> {
protected void onPreExecute(String f) {
// called before doInBackground has started
f = "f";
}
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
// Create a new HTTP client
HttpClient client = new DefaultHttpClient();
// Create a new HTTP Post
HttpPost post = new HttpPost("http://192.xxx.xxx.xxx/androidp2p/process.php");
try {
// Add the data
List<NameValuePair> pairs = new ArrayList<NameValuePair>(3);
pairs.add(new BasicNameValuePair("from", myBreadfromr));
pairs.add(new BasicNameValuePair("to", myBreadtor));
pairs.add(new BasicNameValuePair("message", "What is your location?"));
// Encode Post data into valid URL format
post.setEntity(new UrlEncodedFormEntity(pairs));
// Go back to the first page
Intent back2start = new Intent(RequestLocation.this, StartApp.class);
startActivity(back2start);
// Make the HTTP Post Request
HttpResponse response = client.execute(post);
// Convert the response into a String
final HttpEntity resEntity = response.getEntity();
// Write the response to a log file
if (resEntity != null) {
Log.i("RESPONSE", EntityUtils.toString(resEntity));
}
runOnUiThread(new Runnable(){
public void run() {
Toast.makeText(RequestLocation.this, resEntity.toString(), Toast.LENGTH_LONG).show();
}
});
} catch (UnsupportedEncodingException uee) {
uee.printStackTrace();
} catch (ClientProtocolException cpe) {
cpe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
// called when the background task has made any progress
}
protected void onPostExecute() {
// called after doInBackground has finished
}
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
What I see in the Toast instead is: "org.apache.http.conn.BasicManagedEntity#41284b48".
Thanking you in advance for any help in resolving this matter.
Use EntityUtils.toString(resEntity) in the Toast to get the same text.
Also no need to call runOnUiThread, doInBackground must return something, not null, and that something will be available onPostExecute which already is made to run on the UI thread.
AsyncTask
Related
I am trying to create a Login function so i can verify the users. I pass the Username , Password variables to AsyncTask class but i don't know hot to get results in order to use them. Any help? (I am posting part of the source code due to website restrictions)
btnLogin.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(txtUsername.getText().toString().trim().length() > 0 && txtPassword.getText().toString().trim().length() > 0)
{
// Retrieve the text entered from the EditText
String Username = txtUsername.getText().toString();
String Password = txtPassword.getText().toString();
/*Toast.makeText(MainActivity.this,
Username +" + " + Password+" \n Ready for step to post data", Toast.LENGTH_LONG).show();*/
String[] params = {Username, Password};
// we are going to use asynctask to prevent network on main thread exception
new PostDataAsyncTask().execute(params);
// Redirect to dashboard / home screen.
login.dismiss();
}
else
{
Toast.makeText(MainActivity.this,
"Please enter Username and Password", Toast.LENGTH_LONG).show();
}
}
});
Then i use the AsynkTask to do the check but do not know how to get the results and store them in a variable. Any help?
public class PostDataAsyncTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
// do stuff before posting data
}
#Override
protected String doInBackground(String... params) {
try {
// url where the data will be posted
String postReceiverUrl = "http://server.com/Json/login.php";
Log.v(TAG, "postURL: " + postReceiverUrl);
String line = null;
String fail = "notok";
// HttpClient
HttpClient httpClient = new DefaultHttpClient();
// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);
// add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("UserName", params[0]));
nameValuePairs.add(new BasicNameValuePair("Password", params[1]));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
line = resEntity.toString();
Log.v(TAG, "Testing response: " + line);
if (resEntity != null) {
String responseStr = EntityUtils.toString(resEntity).trim();
Log.v(TAG, "Response: " + responseStr);
Intent Hotels_btn_pressed = new Intent(MainActivity.this, Hotels.class);
startActivity(Hotels_btn_pressed);
// you can add an if statement here and do other actions based on the response
Toast.makeText(MainActivity.this,
"Error! User does not exist", Toast.LENGTH_LONG).show();
}else{
finish();
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String lenghtOfFile) {
// do stuff after posting data
}
}
Not the best code refactoring, but just to give you a hint.
I would create an interface (lets call it 'LogInListener'):
public interface LoginListener {
void onSuccessfulLogin(String response);
void onFailedLogin(String response);
}
The 'MainActivity' class would implement that interface and set itself as a listener the 'PostDataAsyncTask'. So, creating the async task from the main activity would look like this:
String[] params = {Username, Password};
// we are going to use asynctask to prevent network on main thread exception
PostDataAsyncTask postTask = new PostDataAsyncTask(this);
postTask.execute(params);
I would move 'PostDataAsyncTask' class into a new file:
public class PostDataAsyncTask extends AsyncTask<String, String, String> {
private static final String ERROR_RESPONSE = "notok";
private LoginListener listener = null;
public PostDataAsyncTask(LoginListener listener) {
this.listener = listener;
}
#Override
protected String doInBackground(String... params) {
String postResponse = "";
try {
// url where the data will be posted
String postReceiverUrl = "http://server.com/Json/login.php";
// HttpClient
HttpClient httpClient = new DefaultHttpClient();
// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);
// add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("UserName", params[0]));
nameValuePairs.add(new BasicNameValuePair("Password", params[1]));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
postResponse = EntityUtils.toString(resEntity).trim();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return postResponse;
}
#Override
protected void onPostExecute(String postResponse) {
if (postResponse.isEmpty() || postResponse.equals(ERROR_RESPONSE) ) {
listener.onFailedLogin(postResponse);
} else {
listener.onSuccessfulLogin(postResponse);
}
}
}
So, 'doInBackground' returns the response to 'onPostExecute' (which runs on the UI thread), and 'onPostExecute' routes the result (success or failure) to the MainActivity, which implements the 'LogInListener' methods:
#Override
public void onSuccessfulLogin(String response) {
// you have access to the ui thread here - do whatever you want on suscess
// I'm just assuming that you'd like to start that activity
Intent Hotels_btn_pressed = new Intent(this, Hotels.class);
startActivity(Hotels_btn_pressed);
}
#Override
public void onFailedLogin(String response) {
Toast.makeText(MainActivity.this,
"Error! User does not exist", Toast.LENGTH_LONG).show();
}
I just assumed that that's what you wanted to do on success: start a new activity, and show a toast on fail.
public class GetUserDetail extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
mProgressDialog=ProgressDialog.show(PropertyDetailActivitys.this, "Wait", "User Detail");
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
System.out.println("Size mArrayListReviewDetails "+mArrayListReviewDetails.size());
for (int i = 0; i < mArrayListReviewDetails.size(); i++) {
String jsonStr = sh.makeServiceCall("https://graph.facebook.com/"+mArrayListReviewDetails.get(i).getFromid(), ServiceHandler.GET);
System.out.println("JSON OP USer"+"{"+"\"User\""+":"+jsonStr.toString()+"}");
try {
JSONObject jsonObj = new JSONObject(jsonStr);
System.out.println("Name "+jsonObj.getString("name"));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (mProgressDialog!=null) {
mProgressDialog.dismiss();
}
}
}
ServiceHandler.Java
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* #params - http request params
* */
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
Hello friends this is my code in this i have mArrayListReviewDetails Arraylist which include size and as per that size i want to get user name which i call next web service as below ,,right now this arraylist size is 11 but when i call this service it will get only 2 data and progress dialog progress continueouly so how can i solve it any idea?
you just make change in doINBackground fun. Take
ServiceHandler sh = new ServiceHandler(); line inside for loop
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
// Making a request to url and getting response
System.out.println("Size mArrayListReviewDetails "+mArrayListReviewDetails.size());
for (int i = 0; i < mArrayListReviewDetails.size(); i++) {
ServiceHandler sh = new ServiceHandler();
String jsonStr = sh.makeServiceCall("https://graph.facebook.com/"+mArrayListReviewDetails.get(i).getFromid(), ServiceHandler.GET);
System.out.println("JSON OP USer"+"{"+"\"User\""+":"+jsonStr.toString()+"}");
try {
JSONObject jsonObj = new JSONObject(jsonStr);
System.out.println("Name "+jsonObj.getString("name"));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
return null;
}
You could pass your parameters to the async task:
public class GetUserDetail extends AsyncTask<String, Void, Void> {
// ...
#Override
protected Void doInBackground(String... usernames) {
for (int i = 0; i < usernames.length; i++) {
String jsonStr = sh.makeServiceCall("https://graph.facebook.com/" + usernames[i], ServiceHandler.GET);
// ...
}
}
}
Of course, instead of String, feel free to pass your own type. To call the async task:
new GetUserDetail().execute( "test1", "test2" );
Other option is to have each async task perform exactly one single webservice call and create many of them. Advantage: on Android 3.0+, the task executions will be done in parralel.
I think instead of using that...you can use "Volley" library...it's simple and having build-in functionality like;
Request queuing and prioritization
Effective request cache and memory management
Extensibility and customization of the library to our needs
Cancelling the requests
volley reference
volley tutorial
I'm so close to solving the phpMyAdmin connection, but still after onclicked nothing has happend, no error, no freeze. What is wrong here? Or maybe in my PHP code?
final String suma = Float.valueOf(zam.getSuma()).toString();
ib_wyslij.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new MyAsyncTask().execute(suma);
}
});
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) {
Toast.makeText(getApplicationContext(), "command sent",
Toast.LENGTH_LONG).show();
}
public void postData(String valueIWantToSend) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.kuba.ro/exeConn.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("Zam_suma",
valueIWantToSend));
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
}
}
}
Part of my PHP file:
$Zam_suma = $_POST['Zam_suma'];
mysql_query("INSERT INTO Zamowienie(Zam_suma) VALUES($Zam_suma)");
For what do you need the params Integer and Double in your asynctask? If you only need the asynctask to post the string, you can use Void for the other parameters:
private class MyAsyncTask extends AsyncTask<String, Void, Void>
Add the #Override annotation to the onPostExecute() to override the method (see Arjan's answer).
Call e.printStackTrace() in your catch blocks to see when, where and why an error occurs.
Good tutorial
For your PHP file:
Be sure to validate the posted item via PHP, that you are receiving the right value using
is_int is_string, etc.
If your value is supposed to be int, use the following code example.
if (is_int($_POST['example_value']) {
$value = $_POST['example_value'];
}
Also you should not use mysql_query, because it's nearly deprecated. Instead, you should use PDO mysqli.
I'm developing an Android app. I want to post to a server using asynctask. However, I still have an error which indicates that the UI thread is blocked.
I want to parse the XML response and display it in a list view, but I cannot proceed because the UI thread is still blocked.
public class AsynchronousPost extends ListActivity implements OnClickListener {
EditText SearchValue;
Button SearchBtn;
String URL = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_interface);
SearchBtn = (Button) findViewById(R.id.searchbtn);
SearchBtn.setOnClickListener(this);
}
public void onClick(View views) {
new MyAsyncTask().execute();
}
private class MyAsyncTask extends AsyncTask<String, Integer, Document> {
private final String URL = "url";
private final String username = "username";
private final String password = "password";
private EditText SearchValue;
#Override
protected Document doInBackground(String... arg0) {
// TODO Auto-generated method stub
getXmlFromUrl(URL); // getting XML
return null;
}
#Override
protected void onPostExecute() {
//want to parse xml response
//display on listview
}
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
SearchValue = (EditText) findViewById(R.id.search_item);
String Schvalue = SearchValue.getText().toString();
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
5);
nameValuePairs
.add(new BasicNameValuePair("username", username));
nameValuePairs
.add(new BasicNameValuePair("password", password));
nameValuePairs.add(new BasicNameValuePair("searchItem",
Schvalue));
// response stored in response var
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
} catch (ClientProtocolException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
// return XML
return xml;
}
}
}
There are a couple problems that I see. First, you aren't passing anything in execute() but in your class declaration you are telling doInBackground() to expect a String. Secondly, you are telling onPostExecute() to expect a Document but you are returning null from doInBackground() and not taking any parameters in onPostExecute(). Unless I missed something, I don't see how this even compiles
protected Object doInBackground(String... params) {
//this method of AsyncTask is not running on the UI Thread -- here do just non UI taks
return result;
}
#Override
protected void onPostExecute(Object result) {
//I'm not sure but I think this method is running on the UI Thread
//If you have long operations here to do you will block UI Thread
//put the tasks in the doInBackground...
//to fill the elements in the UI elements use
//
runOnUiThread (new Runnable() {
#Override
public void run() {
//here fill your UI elements
}});
}
Here I am trying to retrieve the response from the server and display it, but I am failed to do so, the response text does not appear in my text view, insetead the default value of the string does, may I ask how can I achieve my goal. And why my code cannot finish the task.
Here is my android program:
public class Chico extends Activity {
GrabURL grab;
TextView mRespond;
String line;
#Override
public void onCreate(Bundle savedInstanceState) {
//create the activity
super.onCreate(savedInstanceState);
//set up the layout
setContentView(R.layout.activity_chico);
mRespond = (TextView) findViewById(R.id.Respond);
mRespond.setVisibility(View.GONE);
grab = new GrabURL();
line = "line";
//set up the button for check in
Button btnin = (Button) findViewById(R.id.inbutton);
btnin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//set the values
grab.onPreExecute("TechID", Build.SERIAL);
grab.onPreExecute("Type", "Checkin");
//set the destination and send the request
grab.execute(new String[]{"http://192.168.1.150/Me/testing.php"});
//close the activity
mRespond.setVisibility(View.VISIBLE);
mRespond.setText(line);
//finish();
}
});
}
private class GrabURL extends AsyncTask<String, Void, Void>{
//ArrayList object for storing the string pairs
ArrayList<NameValuePair> nameValuePairs;
public GrabURL() {
//constructor of the class
nameValuePairs = new ArrayList<NameValuePair>();
}
protected void onPreExecute(String key, String value) {
//store the pair of values into the ArrayList
nameValuePairs.add(new BasicNameValuePair(key,value));
}
#Override
protected Void doInBackground(String... urls) {
// TODO Auto-generated method stub
//Operation being executed in another thread
try{
//set up the type of HTTPClient
HttpClient client = new DefaultHttpClient();
//set up the location of the server
HttpPost post = new HttpPost(urls[0]);
//translate form of pairs to UrlEncodedFormEntity
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8);
//set up the entity being sent by post method
post.setEntity(ent);
//execute the url and post the values
HttpResponse responsePOST = client.execute(post);
HttpEntity resEntity = responsePOST.getEntity();
line = EntityUtils.toString(resEntity);
} catch (Exception e) {
//catch the exception
line = "Can't connect to server";
}
return null;
}
protected void onPostExecute(Void unused) {
Toast.makeText(getApplicationContext(), "Value updated", Toast.LENGTH_SHORT).show();
}
}
}
And here is the php file, it just prints a line:
<?php
print "testing";
?>
Move this code to your AsyncTask's onPostExecute():
...
mRespond.setVisibility(View.VISIBLE);
mRespond.setText(line);