I'm trying to use gson to connect to a server but i have a problem with the code, I found out that you need AsyncTask for network connections since it would not run in the main thread, hence the exception I got as stated in the title.
public class SendPostRequest extends AsyncTask<String, Void, String> {
private Gson gson = new GsonBuilder().create();
public String sendMessage(Object message, String address) {
String url = "http://192.168.87.108:8080/MSS/" + address;
String data = gson.toJson(message);
HttpPost post = new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("report", data));
try {
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
} catch (UnsupportedEncodingException e) {
System.out.println("Your url encoding is shiat fail");
e.printStackTrace();
}
HttpClient client = new DefaultHttpClient();
HttpResponse response = null;
try {
response = client.execute(post);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
String responseText = "";
try {
responseText = EntityUtils.toString(entity);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return responseText;
}
#Override
protected String doInBackground(String... params) {
return "";
}
}
I am aware i need to move the code into the doInBackground method, but I also need to use the SendMessage method with its parameters by calling it in other classes to correspond with the server parameters(like save, register, etc), so i'm not sure how to go about moving the contents so it would work as an AsyncTask. Any help would be appreciated, thank you
AsyncTask takes one type of parameter, String in your case, so I changed sendMessage method to take String data instead of Object message (so you will just convert the Object message to JSON string before executing the task, it doesn't involve networking, and rather won't be very time consuming):
public class SendPostRequest extends AsyncTask<String, Void, String> {
public String sendMessage(String data, String address) {
[..]
}
#Override
protected String doInBackground(String... params) {
return sendMessage(params[0], params[1]);
}
#Override
protected void onPostExecute(String result) {
Area[] og = gson.fromJson(result, Area[].class);
}
}
All the network stuff must be done inside doInBackground method. Execute the task that way:
new SendPostRequest().execute(data, address);
Passing the data, and address the the execute method. data will be then mapped to params[0] and address to params[1] and accessible from doInBackground method. params variable is just an array of all arguments you passed to execute method.
Both data and address must be String in that case, because it is the type declared in AsyncTask<String, Void, String>.
Related
It is somthing very weird.
I am using my android device to send messages to my node js server in LAN.
And now here comes the problem: When I send POST HTTP it DOES work. But when I send GET HTTP it DOES NOT work and the server even not recieve the get request.
This is my code for recieving the get:
app.get('/auth/facebook', passport.authenticate('facebook'));
And this is the code in androif for sending the GET:
public class Background_confirmation extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// progressDialog = ProgressDialog.show(Confirmation.this, "Please wait...", "Retrieving data ...", true);
}
#Override
protected String doInBackground(Void... params) {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://localhost:8080/auth/facebook");
// replace with your url
HttpResponse response = null;
try {
response = client.execute(request);
Log.d("Response of GET request", response.toString());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response.toString();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// progressDialog.setCancelable(true);
// }
}
Someone have an idea for why it happen?
You are trying to get the data from localhost (i.e., your Android device) instead of from your server.
okay so i created a inner class which extends AsycTask in order for my code to run outwith the UI thread. However i'm getting this error so i assume this means some part of my onPostExecute needs to be done in doInBackground however i cant figure out exactly what this is
public class asyncTask extends AsyncTask<String, Integer, String> {
ProgressDialog dialog = new ProgressDialog(PetrolPriceActivity.this);
#Override
protected void onPreExecute() {
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
dialog.setMax(100);
dialog.setMessage("loading...");
dialog.show();
}
#Override
protected String doInBackground(String...parmans){
{
for(int i = 0; i < 100; i++){
publishProgress(1);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String urlString = petrolPriceURL;
String result = "";
InputStream anInStream = null;
int response = -1;
URL url = null;
try {
url = new URL(urlString);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
return null;
}
URLConnection conn = null;
try {
conn = url.openConnection();
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
// Check that the connection can be opened
if (!(conn instanceof HttpURLConnection))
try {
throw new IOException("Not an HTTP connection");
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
try
{
// Open connection
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
// Check that connection is OK
if (response == HttpURLConnection.HTTP_OK)
{
// Connection is OK so open a reader
anInStream = httpConn.getInputStream();
InputStreamReader in= new InputStreamReader(anInStream);
BufferedReader bin= new BufferedReader(in);
// Read in the data from the RSS stream
String line = new String();
while (( (line = bin.readLine())) != null)
{
result = result + "\n" + line;
}
}
}
catch (IOException ex)
{
try {
throw new IOException("Error connecting");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return result;
}
}
#Override
protected void onProgressUpdate(Integer...progress){
dialog.incrementProgressBy(progress[0]);
}
#Override
protected void onPostExecute(String result) {
// Get the data from the RSS stream as a string
errorText = (TextView)findViewById(R.id.error);
response = (TextView)findViewById(R.id.title);
try
{
// Get the data from the RSS stream as a string
result = doInBackground(petrolPriceURL);
response.setText(result);
Log.v(TAG, "index=" + result);
}
catch(Exception ae)
{
// Handle error
errorText.setText("Error");
// Add error info to log for diagnostics
errorText.setText(ae.toString());
}
if(dialog.getProgress() == dialog.getMax())
dialog.dismiss();
}
}
if someone could point out my error as well as show an example of where the code is suppose to go in my doInBackground that would be great. Thanks
problem:
result = doInBackground(petrolPriceURL);
you are implicitly calling the doInbackground method in the onPostExecute which will actually run in your UI thread instead on a different thread thus resulting to Android:NetworkOnMainThreadException.
Also it is unnecessary to call doInBackground that it is already executed before onPostExecute when you execute your Asynctask. Just directly use the result parameter of the onPostExecute.
sample:
#Override
protected void onPostExecute(String result) {
// Get the data from the RSS stream as a string
errorText = (TextView)findViewById(R.id.error);
response = (TextView)findViewById(R.id.title);
response.setText(result);
if(dialog.getProgress() == dialog.getMax())
dialog.dismiss();
}
I suspect the error is related to this part of your code:
try
{
// Get the data from the RSS stream as a string
result = doInBackground(petrolPriceURL);
response.setText(result);
Log.v(TAG, "index=" + result);
}
doInBackgound is called automatically when you call asynctask.execute. To start your task correctly you should (1) create a new instance of your task; (2) pass the string params you need to use in doInBackground in the execute method; (3) use them; (4) return the result to onPostExecute.
For Example:
//in your activity or fragment
MyTask postTask = new MyTask();
postTask.execute(value1, value2, value3);
//in your async task
#Override
protected String doInBackground(String... params){
//extract values
String value1 = params[0];
String value2 = params[1];
String value3 = params[2];
// do some work and return result
return value1 + value2;
}
#Override
protected void onPostExecute(String result){
//use the result you returned from you doInBackground method
}
You should try to do all of your "work" in the doInBackground method. Reutrn the result you want to use on the main/UI thread. This will automaticlly be passed as an argument to the onPostExecute method (which runs on the main/UI thread).
Here is my android code for post data to remote db, It doesn't work as I wish, well, it doesn't work at all. No errors, no actions. Help guys. I really don't know what is going on.. Any advice is welcome.
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, Void, Void> {
#Override
protected Void 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.msinzynierka.cba.pl/executeConn.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
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Here is my execution php script
[logging & connecting ]
.
.
.
.
$Zam_suma = $_POST['Zam_suma'];
mysql_query("INSERT INTO Zamowienie(Zam_suma) VALUES($Zam_suma)");
You need to read about AsyncTask the way it is setup is incorrect. I don't know if its your problem or not but you should understand the params.
private class MyAsyncTask extends AsyncTask<String, Void, Void> {
The first is what is passed to doInBackground() during your execution...this looks fine.
The second is what onProgressUpdate() takes...this also looks fine since you don't implement that method.
The third is what is passed to onPostExecute() from the return in doInBackground()...this doesn't look fine. You are telling onPostExecute()to expect nothing and returning nothing indoInBackground()which would be correct but then youronPostExecute()` should look like
protected void onPostExecute(Void result) {
Since your method signature is incorrect, you aren't actually overriding the AsyncTask method but it thinks that it is your own method and won't run when doInBackground() has finished. This is where the #Override annotation comes in handy.
I have a method written like this...
public void getRequest(String Url) {
runOnUiThread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
try {
HttpResponse response = client.execute(request);
Toast.makeText(MenuUtama.this, request(response) ,Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
I need to be able to access the local variable request in another method, so that I can call request.response. How am I able to access this local method from a totally different method?
Increase the scope of variables of response and and request,I mean declare these variable at class level not in method level.
You cannot call any variable declare as a local variable inside any function. you can do that in a way as follows
public class A{
HttpGet request;
HttpResponse response;
void methodA(){
request = //........
response = //...........
}
void methodB{
//here you can refer to request and response as they are the instance variables of the class.
}
}
If you want to access those from outside the class, then you have to create an object of class A and then call as follows
A a = new A();
//now you can call a.request or a.response
But remember the variables access specifiers should allow you to do this.
I think what you're looking for is something along these lines:
protected Object myRequest;
public void getRequest(String Url) {
runOnUiThread(new Runnable() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
try {
HttpResponse response = client.execute(request);
myRequest = request(response);
Toast.makeText(MenuUtama.this, myRequest, Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
Obviously change Object to whatever class request(response) works out to be, rename myRequest, and preferrably use accessors on a private instance variable rather than making it protected and assigning directly, but you get the point, hopefully, that you need an instance variable to hold the value of your method call request(response).
you should declare your response variable in a class-level scope. here's your code.
public class YourClass{
//Declare your request varible in a class-level scope
//so it can be accessed by any method
HttpGet request;
public void getRequest(String Url) {
runOnUiThread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
try {
response = client.execute(request);
Toast.makeText(MenuUtama.this, request(response) ,Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
public void otherMthod(){
System.out.println(request); //request variable is accessible in this scope.
}
}
I'm still struggling to find an answer to my question. I want to download 3 strings for each item in the listview to the phone. I know how to get all the data from the server, just not how to append the data to the litview, I'm really annoyed and this problem is dragging me down.
My Code:
public class ChatService extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chatservice);
try {
ContactsandIm();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CheckLogin();
private void CheckLogin() {
// TODO Auto-generated method stub
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
/* login.php returns true if username and password is equal to saranga */
HttpPost httppost = new HttpPost("http://gta5news.com/login.php");
try {
// Execute HTTP Post Request
Log.w("HttpPost", "Execute HTTP Post Request");
HttpResponse response = httpclient.execute(httppost);
String str = inputStreamToString(response.getEntity().getContent())
.toString();
Log.w("HttpPost", str);
if (str.toString().equalsIgnoreCase("true")) {
Log.w("HttpPost", "TRUE");
try {Thread.sleep(250);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//put intent here(21/3/12);
} else {
Log.w("HttpPost", "FALSE");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private StringBuilder inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Return full string
return total;
}
private void ContactsandIm() throws URISyntaxException, ClientProtocolException, IOException {
// TODO Auto-generated method stub
BufferedReader in = null;
String data = null;
HttpClient get = new DefaultHttpClient();
URI website = new URI("http://www.gta5news.com/test.php");
HttpGet webget = new HttpGet();
webget.setURI(website);
HttpResponse response = get.execute(webget);
Log.w("HttpPost", "Execute HTTP Post Request");
in = new BufferedReader (new InputStreamReader(response.getEntity().getContent()));
//now we'll return the data that the PHP set from the MySQL Database.
if (in.equals("True")); {
Toast.makeText(this,"yay", Toast.LENGTH_LONG).show();
}
}
// end bracket for "ContactsandIm"
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
Use an ArrayAdapter on your list, and add items to this adapter, then call notifyDatasetChanged on it, and zou
First of all when we connect to Server using the Network Threads, then you should go for AsyncTask or Handlers. Which is specially used for handling such Threads.
ListView can be created by using default Listview ans also the Custom Listview where we can design our own Row design in the Row.xml and the same design will be used for all the rows.
If you want move forward or go for some advanced Listview then even we can use 'n' number of designs for different rows.
Here in your case, You should use a AsyncTask for fetching the data and use the Listview for displaying rows.
You can get more information from the below link.
https://docs.google.com/leaf?id=0B2qCFbmeiTFxN2ViZjVlOTUtNmY3ZS00NThhLTg3N2UtYjVkYjgyM2Y4MWUy&hl=en&authkey=COeP8JYN