Accessing Web Service from Android Application


           It is easy to communicate with a web service from an Android application. All you need is a active web service, its WSDL url, web method name, web service name space and ksoap2 library.

ksoap2 is a lightweight SOAP client library for Android platform.


Before going into the android application, make sure that you have a active web service running in your machine. If you do not have one, follow this to create a simple web service using axis2.
Once you create the web service, get its wsdl url, namespace and the web method name.

In your WSDL file search for "targetNamespace". This will have the namespace value.
wsdl:operation name will have the web method name. The android application will invoke this method.

The WSDL I have used for this example is shown below (which is also given in this tutorial),


Adding ksoap2 library to the project:
Download ksoap2 library with dependencies jar.
One of the download locations are https://code.google.com/p/ksoap2-android/
Copy the jar > Right click on the lib folder and paste it.



Important things:
It is advisable to use AsyncTask for calling the web service. Network operations are not allowed in the main thread in android. To know more about AsyncTask and its usage visit this tutorial.

Once you are ready with all these things, it is just a four statements to call the web service

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
  SoapEnvelope.VER11);
SoapObject request = new SoapObject(NAMESPACE, METHOD);
//bodyOut is the body object to be sent out with this envelope
envelope.bodyOut = request;
HttpTransportSE transport = new HttpTransportSE(URL);
transport.call(NAMESPACE + SOAP_ACTION_PREFIX + METHOD, envelope);

envelope.bodoOut is used to send the soap body to the web service, envelop.bodyIn is used to receive the response from the web service.
SoapPrimitive resultSOAP = (SoapPrimitive) ((SoapObject) envelope.bodyIn)
       .getProperty(0);
response=resultSOAP.toString();

You need to add android.permission.INTERNET in your androidManifest.xml to perform network operations from your application.

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

Sample application:
This sample application calls the web service in AsyncTask and shows the response from the web service in TextView. My web service just returns a string value.

/**
 *
 */
package sample;

/**
 * @author Vienna
 *
 */
public class WebService {
 public String getName(){
  return "Test";
 }
}


AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.samplews"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.samplews.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>


AndroidLayout file: activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="28dp"
        android:layout_marginTop="23dp" />

</RelativeLayout>


Activity class: MainActivity.java
package com.example.samplews;

import java.io.IOException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;

/**
 * Accessing Web service in Android application 
 * @author Prabu
 * @version 1.0
 * @since SEP 10 2013
 */
public class MainActivity extends Activity {
 public final static String URL = "http://192.168.1.102/WebService/services/WebService?wsdl";
 public static final String NAMESPACE = "http://sample";
 public static final String SOAP_ACTION_PREFIX = "/";
 private static final String METHOD = "getName";
 private TextView textView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  textView = (TextView) findViewById(R.id.test);
  AsyncTaskRunner runner = new AsyncTaskRunner();
  runner.execute();
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
 }

 /**
  * Private class which runs the long operation.
  * @author Prabu 
  * 
  */
 private class AsyncTaskRunner extends AsyncTask<String, String, String>        {

   private String resp;
   @Override
   protected String doInBackground(String... params) {
     publishProgress("Loading contents..."); // Calls onProgressUpdate()
     try {
       // SoapEnvelop.VER11 is SOAP Version 1.1 constant
       SoapSerializationEnvelope envelope = new SoapSerializationEnvelop                                                   e(SoapEnvelope.VER11);
              SoapObject request = new SoapObject(NAMESPACE, METHOD);
       //bodyOut is the body object to be sent out with this envelope
       envelope.bodyOut = request;
       HttpTransportSE transport = new HttpTransportSE(URL);
       try {
         transport.call(NAMESPACE + SOAP_ACTION_PREFIX + METHOD, envelope);
       } catch (IOException e) {
         e.printStackTrace();
       } catch (XmlPullParserException e) {
         e.printStackTrace();
     }
   //bodyIn is the body object received with this envelope
   if (envelope.bodyIn != null) {
     //getProperty() Returns a specific property at a certain index.
     SoapPrimitive resultSOAP = (SoapPrimitive) ((SoapObject) envelope.bodyIn).getProperty(0);
     resp=resultSOAP.toString();
   }
 } catch (Exception e) {
   e.printStackTrace();
   resp = e.getMessage();
 }
 return resp;
      }

  /**
   * 
   * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
   */
  @Override
  protected void onPostExecute(String result) {
 // execution of result of Long time consuming operation
 // In this example it is the return value from the web service
 textView.setText(result);
  }

  /**
   * 
   * @see android.os.AsyncTask#onPreExecute()
   */
  @Override
  protected void onPreExecute() {
 // Things to be done before execution of long running operation. For
 // example showing ProgessDialog
  }
  /**
   * 
   * @see android.os.AsyncTask#onProgressUpdate(Progress[])
   */
  @Override
  protected void onProgressUpdate(String... text) {
 textView.setText(text[0]);
 // Things to be done while execution of long running operation is in
 // progress. For example updating ProgessDialog
  }
}
}


Output:


Source code of this application:
SampleWS.zip

 



Reactions:

14 comments :

  1. i am using asp web service i am getting exception

    java.net.ConnectionException: filed to connect to localhost/127.0.0.1 (port 38363) after 20000ms: isConnection Failed: ECONNREFUSED (Connection refused)

    can you tell me what is the problem

    ReplyDelete
    Replies
    1. Instead of localhost/127.0.0.1 try this 10.0.2.2 which is localhost IP for Android

      Delete
  2. I have a problem, during setting soap header, please see my problem in statckoverflow: http://stackoverflow.com/questions/23244189/soap-header-not-getting-in-android-and-how-to-get-soap-header-in-wcf

    ReplyDelete
  3. Please talk you, my web service of url is http://localhost:8080/WebService/services/WebService?wsdl.
    In Android developer of url what

    ReplyDelete
  4. Works on emulator but not on my android device. What should be done for that?

    ReplyDelete
    Replies
    1. Webservice should be hosted on internet.

      Delete
  5. It shows only Loading Content...
    then nothing. I have my web service on localhost. I addressed it as 10.0.0.2
    Wht is the problem?

    ReplyDelete
    Replies
    1. Hello,

      I have the same problem. Did you get the solution ?

      Delete
  6. my web service is being loaded on emulator but for all the values it returns only the exception statement. So please tell what is the problem .

    ReplyDelete
  7. I am getting this error

    org.ksoap2.SoapFault cannot be cast to org.ksoap2.serialization.SoapObject

    What does this mean and how to fix it? Thanks

    ReplyDelete
  8. Hi, i have problem, can u help me?

    How can i pass object to WS and get response return object?

    ReplyDelete
  9. I have implemented the whole logic of Soap Webservice as given in the article. It is working in Eclipse but whenever i use the same in Android studio/ Intellij 15 , it does not show anything. There is no error and i can run the app but nothing happend when i rub. Please suggest what the problem. Thanks

    ReplyDelete