I'm trying to learn to use SOAP via java (android). I followed this tutorial and I've created the code below:
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class MainActivity extends AppCompatActivity {
String TAG = "Response";
String value;
Button btn;
EditText val;
TextView fahr;
TextView cels;
SoapPrimitive result;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.convert_btn);
val = (EditText) findViewById(R.id.value);
fahr = (TextView) findViewById(R.id.f);
cels = (TextView) findViewById(R.id.c);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick (View view) {
value = val.getText().toString();
AsyncCallWS ac = new AsyncCallWS();
ac.execute();
}
});
}
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
@Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
calculate();
return null;
}
@Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
if (result != null) {
cels.setText(result.toString());
}
}
}
public void calculate() {
String SOAP_ACTION = "http://www.w3schools.com/xml/FahrenheitToCelsius";
String METHOD_NAME = "FahrenheitToCelsius";
String NAMESPACE = "http://www.w3schools.com/xml/";
String URL = "http://www.w3schools.com/xml/tempconvert.asmx";
try {
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
Request.addProperty("Fahrenheit", 15);
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(Request);
HttpTransportSE transport = new HttpTransportSE(URL);
transport.call(SOAP_ACTION, soapEnvelope);
result = (SoapPrimitive) soapEnvelope.getResponse();
Log.i(TAG, "Result Celsius: " + result);
} catch (Exception ex) {
ex.printStackTrace();
Log.e(TAG, "Error: " + ex.getMessage());
}
}
}
Whenever I run it I get java.net.SocketTimeoutException at transport.call()
Googling it and searching through SO didn't help much.
I'm using the www.w3schools.com webservice and the URL loads perfectly through my browser.
Note: If I copy and paste the code from the example, it works as expected. However if I write the code by hand (mostly identical) it throws this exception. The only thing I'm changing from the tutorial is how the result will be posted on the UI.
EDIT: The stack trace is as follows:
java.net.SocketTimeoutException
07-05 06:51:16.094 2734-2777/com.kostas.tade W/System.err: at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:130)
07-05 06:51:16.094 2734-2777/com.kostas.tade W/System.err: at com.kostas.tade.MainActivity.calculate(MainActivity.java:90)
07-05 06:51:16.094 2734-2777/com.kostas.tade W/System.err: at com.kostas.tade.MainActivity$AsyncCallWS.doInBackground(MainActivity.java:60)
07-05 06:51:16.098 2734-2777/com.kostas.tade W/System.err: at com.kostas.tade.MainActivity$AsyncCallWS.doInBackground(MainActivity.java:51)
07-05 06:51:16.107 2734-2777/com.kostas.tade W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:292)
07-05 06:51:16.107 2734-2777/com.kostas.tade W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-05 06:51:16.110 2734-2777/com.kostas.tade W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-05 06:51:16.110 2734-2777/com.kostas.tade W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-05 06:51:16.110 2734-2777/com.kostas.tade W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-05 06:51:16.110 2734-2777/com.kostas.tade W/System.err: at java.lang.Thread.run(Thread.java:818)
Also the actual calculate()
method is exactly the same one as the example (the one working).
NOT a duplicate to this SO question since that one doesn't have an chosen answer and it addresses the java.net.SocketTimeoutException : Read Timeout
Ok, figured it out. For some reason typing
<uses-permission android:name="android.permission.INTERNET"/>
in the AndroidManifest.xml
file didn't do it. However copying and pasting the permission from the working project, fixed it.
I'm guessing it was a bug on android studio. Anyway, thank you for your help.