Monday 16 September 2013

[Android] Calling SOAP Web Service

Android App is able to call Web Service using SOAP.

1) create a new Android project as usual. Name the activity file as main.xml.

2) Download the ksoap2-android-assembly-2.6.0-jar-with-dependencies.jar library and copy it to the project libs folder

3) Right click on the project name, select Java Build Path->Libraries, click on "Add JARs...", and add the jar library

4) In the same dialog box, click on "Order and Export", and click the jar library and move it up. Make sure the jar is above Android Dependencies and Private Libraries.

5) Modify the main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fahrenheit"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <EditText
        android:id="@+id/txtFar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <requestFocus />
    </EditText>
    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Celsius"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <EditText
        android:id="@+id/txtCel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <Button
            android:id="@+id/btnFar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="Convert To Celsius" />
        <Button
            android:id="@+id/btnCel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="Convert To Fahrenheit" />
    </LinearLayout>
    <Button
        android:id="@+id/btnClear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Clear" />
</LinearLayout>

6) Make use and understand the ksoap2 class

  • SOAPObject
  • SoapSerializationEnvelope
  • HttpTransportSE
Initialise the SoapObject, the namespace and method name are gotten from wsdl file. Namespace is from <xs:schema targetNamespace="tns" elementFormDefault="qualified">
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

Set the parameter, the parameter are also from wsdl file. The parameter is case-sensitive.
request.addProperty("Fahrenheit", txtFar.getText().toString());

The URL is from <soap:address location="http://mywebsite.com/service"/>
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

Call the soap action, the Soap action is from <soap:operation soapAction="addMyData" style="document"/>
androidHttpTransport.call(SOAP_ACTION1, envelope);

7) Edit the WebServiceDemoActivity.java file.

If you try to access network in the main thread, in Android 4.0 and above, you will get the error of
NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a networking operation on its main thread.

The solution is to create a thread, and access the network in the thread

                        Thread thread = new Thread()
                        {
                            @Override
                            public void run() {
                                try {
                                      //access the network
                                      ......
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        };
                        thread.start();

Furthermore, if you try to update the GUI in the thread, you will get the error:
Only the original thread that created a view hierarchy can touch its views.

The solution is to use runOnUiThread() function to update the UI.

                                runOnUiThread(new Runnable() {
                                    public void run() {
                                        //stuff that updates ui
                                            ......
                                    }
                                });

8) The full source code of WebServiceDemoActivity.java will be published at the bottom.

9) Open your "WebServiceDemo -> android.manifest" file. Add the following line before the <application> tag:

<uses-permission android:name="android.permission.INTERNET" />

This will allow the application to use the internet.



10) Full source code of WebServiceDemoActivity.java:


package com.webservicedemo;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import com.webservicedemo.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class WebServiceDemoActivity extends Activity
{
    /** Called when the activity is first created. */
      private static String SOAP_ACTION1 = "http://tempuri.org/FahrenheitToCelsius";
      private static String NAMESPACE1 = "http://tempuri.org/";
      private static String METHOD_NAME1 = "FahrenheitToCelsius";
      private static String URL1 = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";

      private static String SOAP_ACTION2 = "http://tempuri.org/CelsiusToFahrenheit";
      private static String NAMESPACE2 = "http://tempuri.org/";
      private static String METHOD_NAME2 = "CelsiusToFahrenheit";
      private static String URL2 = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";

      Button btnFar,btnCel,btnClear;
      EditText txtFar,txtCel;
      
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        btnFar = (Button)findViewById(R.id.btnFar);
        btnCel = (Button)findViewById(R.id.btnCel);
        btnClear = (Button)findViewById(R.id.btnClear);
        txtFar = (EditText)findViewById(R.id.txtFar);
        txtCel = (EditText)findViewById(R.id.txtCel);    
        
        btnFar.setOnClickListener(new View.OnClickListener()
        {
                  @Override
                  public void onClick(View v)
                  {           
                       
                        //this is the actual part that will call the webservice

                        Thread thread = new Thread()
                        {
                            @Override
                            public void run() {
                                try {
                                    SoapObject request = new SoapObject(NAMESPACE1, METHOD_NAME1);                                    
                                    //Use this to add parameters
                                    request.addProperty("Fahrenheit",txtFar.getText().toString());
                                    SoapSerializationEnvelope envelope = 
                                        new SoapSerializationEnvelope(SoapEnvelope.VER11);
                                    envelope.setOutputSoapObject(request);
                                    envelope.dotNet = true;
                                    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL1);
                                    androidHttpTransport.call(SOAP_ACTION1, envelope);
                                    // Get the SoapResult from the envelope body.
                                    SoapObject result = (SoapObject)envelope.bodyIn;
                                    if(result != null)
                                    {
                                     final String result_str = result.getProperty(0).toString();
                                     runOnUiThread(new Runnable() {
                                          public void run() {
                                            //stuff that updates ui
                                            //Get the first property and change the label text                                             
                                                 txtCel.setText(result_str);
                                          }
                                     });
                                     ;
                                    }
                                    else
                                    {
                                      Toast.makeText(getApplicationContext(), "No Response",Toast.LENGTH_LONG).show();
                                    }                                    
                               
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        };
                        thread.start();
                  }
         });
       
        btnCel.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {           
                 
                  //this is the actual part that will call the webservice

                  Thread thread = new Thread()
                  {
                      @Override
                      public void run() {
                                                     
                          try {
                              SoapObject request = new SoapObject(NAMESPACE2, METHOD_NAME2);                                    
                              //Use this to add parameters
                              request.addProperty("Celsius",txtCel.getText().toString());
                              SoapSerializationEnvelope envelope = 
                                  new SoapSerializationEnvelope(SoapEnvelope.VER11);
                              envelope.setOutputSoapObject(request);
                              envelope.dotNet = true;
                              HttpTransportSE androidHttpTransport = new HttpTransportSE(URL2);
                              androidHttpTransport.call(SOAP_ACTION2, envelope);
                              // Get the SoapResult from the envelope body.
                              SoapObject result = (SoapObject)envelope.bodyIn;
                              if(result != null)
                              {
                               final String result_str = result.getProperty(0).toString();
                               runOnUiThread(new Runnable() {
                                    public void run() {
                                      //stuff that updates ui
                                      //Get the first property and change the label text                                             
                                           txtFar.setText(result_str);
                                    }
                               });
                               ;
                              }
                              else
                              {
                                    Toast.makeText(getApplicationContext(), "No Response",Toast.LENGTH_LONG).show();
                              }                                    
                         
                          } catch (Exception e) {
                              e.printStackTrace();
                          }
                      }
                  };
                  thread.start();
            }
        });
       
        btnClear.setOnClickListener(new View.OnClickListener()
        {
                  @Override
                  public void onClick(View v)
                  {
                        txtCel.setText("");
                        txtFar.setText("");
                  }
        });
    }
}

No comments:

Post a Comment