Search code examples
javaandroidweb-servicesandroid-ksoap2

Android java.net.SocketTimeoutException


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


Solution

  • 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.