Saturday, February 11, 2012

Android Web Service Access Using ksoap2.

In this tutorial I'm going to demonstrate how we can access a simple java web service  using an Android application. To complete this tutorial you need some knowledge about dynamic web service projects in Eclipse & about ksoap2.

Following is the sample java code for web service class. Deploy this web service on Tomcat server at local host. To implement this web service follow these two posts Post 1 || Post 2
package com.android.ws;
public class PrintMsg {
 public String sayHello(){
           return "Hello Chathura";
        }
}

Following is the code which we can use in Android application to invoke deployed web service.
package com.androidclient.ws;

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 android.widget.TextView;

import android.app.Activity;
import android.os.Bundle;

public class WSClientActivity extends Activity {
    private static final String SOAP_ACTION = "http://ws.android.com/sayHello";
    private static final String METHOD_NAME = "sayHello";
    private static final String NAMESPACE = "http://ws.android.com/";
    private static final String URL = "http://175.157.229.119:8080/AndroidWSTest/services/PrintMsg?wsdl";
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);           

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        
        envelope.setOutputSoapObject(request);

        HttpTransportSE ht = new HttpTransportSE(URL);
        try {
         ht.call(SOAP_ACTION, envelope);
            SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
            
            TextView tv = new TextView(this);
            tv.setText("Message :"+response.toString());
            setContentView(tv);
  
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
}

Here:
SOAP_ACTION in line 14 is "NAMESPACE/METHOD_NAME"

METHOD_NAME
in line 15 is WSDL operation. You can find something like <wsdl:operation name="sayHello"> in your WSDL sayHello is METHOD_NAME here.

NAMESPACE in line 16 is targetNamespace in the WSDL. Replace that & add a "/" to the end .

URL in line 17 The URL of WSDL file. In my case it is http://175.157.229.119:8080
/AndroidWSTest/services/PrintMsg?wsdl
blue colored is the ip of the server replace it with your ip & red colored is the port number

Make appropriate changes  according to your WSDL. Following image will help you.

This is an example image of a WSDL opened using Firefox .


Add Internet permission to Androidanifest.xml file.



    

    
        
            
                

                
            
        
    


Highlighted line shows the necessary changes.
Run the application using Emulator.Result :


Note :
For Android 3.0 and after versions we cannot connect to the internet in the main thread. So we have to start new thread.

Here is the code :

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 android.widget.TextView;
import android.app.Activity;
import android.os.Bundle;

public class AndroidWSClientActivity extends Activity {
 
    private static final String SOAP_ACTION = "http://ws.android.com/sayHello";
    private static final String METHOD_NAME = "sayHello";
    private static final String NAMESPACE = "http://ws.android.com/";
    private static final String URL = "http://175.157.229.119:8080/AndroidWSTest/services/PrintMsg?wsdl";
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
     
    Thread networkThread = new Thread() {
    @Override
    public void run() {
      try {
         SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);          
         SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
         envelope.setOutputSoapObject(request);
         
         HttpTransportSE ht = new HttpTransportSE(URL);
         ht.call(SOAP_ACTION, envelope);
         final  SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
         final String str = response.toString();

         runOnUiThread (new Runnable(){ 
     public void run() {
         TextView result;
         result = (TextView)findViewById(R.id.textView1);//Text view id is textView1
         result.setText(str);
           }
       });
      } 
     catch (Exception e) {
         e.printStackTrace();
     }
    }
  };
  networkThread.start();
  }
 }
}

You can download updated project (for new versions) here
Password : cloud

If you find this post helpful don't forget to leave a comment. Your comments always encourage me to write more!

35 comments:

  1. Thanks,

    your tutorials are very good, thanks :-)

    ReplyDelete
    Replies
    1. Okie, your tutorial is very good, this is my problem that i spent more time to fix. And i fixed it success!!

      Delete
  2. Thank you for your detailed tutorial. It's the first one which actually works.
    But know i've a problem with the different versions of Android. The Client works on Android 2.3.3 but not on Android 4.0.3 As soon as a SoapObject is initialized the Client won't work.
    I tried to apply it on emulator 4.0.3 as well as on my HTC Sensation 4.0.3 and it didn't work.
    Do you have an idea about it?

    ReplyDelete
    Replies
    1. Thanks Marcel for your comment!
      I have updated my post this will help you.

      Delete
    2. Hi Chathura,
      Your update works! Thanks a lot!!!
      I only had one Problem at the beginning:
      Could not find class 'org.ksoap2.serialization.SoapObject',...

      I had to create one directory on root in my project named libs
      and just copy and paste ksop 2.5.. jar into libs dir. Because the ksop 2.5..jar file on root doesn't work in Android 4.0. Then "Build Path" -> Add to Build Path

      Thats solved the Problem.

      Delete
    3. Glad I could help.... and thanks Marcel for your comment..!

      Delete
  3. Thank you for your quick fix. I will try it ;-)
    Happy Easter!

    ReplyDelete
  4. Perfect except one thing. I think namespace and soap_action is wrong order. It should be:
    private static final String SOAP_ACTION = "http://ws.android.com/sayHello/";
    private static final String NAMESPACE = "http://ws.android.com";

    Thanks for effective tutorials!

    ReplyDelete
    Replies
    1. OK! There was a mistake in my previous tutorial. I'm sorry for that. I have fixed that error in this updated tutorial. Thanks for commenting & correcting.
      For new tutorials check this
      www.codeoncloud.blogspot.com

      Delete
  5. Please let me know where can I download ksoap2-android latest jar file. Please it iw very urgent
    Thanks,Gowri

    ReplyDelete
    Replies
    1. At the moment 2.6.3 is the latest version. Check this:::::: http://code.google.com/p/ksoap2-android/source/browse/#svn%2Fm2-repo%2Fcom%2Fgoogle%2Fcode%2Fksoap2-android%2Fksoap2-android-assembly%2F2.6.3
      Direct URL to the jar file here::::::
      http://ksoap2-android.googlecode.com/svn/m2-repo/com/google/code/ksoap2-android/ksoap2-android-assembly/2.6.3/ksoap2-android-assembly-2.6.3-jar-with-dependencies.jar
      Thanks!

      Delete
  6. Thanks!
    Actually, i work with JBoss ws and it is quite different from Apache.
    do you have any tutorial that could help me
    thank you v. much

    ReplyDelete
  7. MarcelApril 11, 2012 3:35 AM
    Thankyouverymuch!!

    ReplyDelete
  8. Replies
    1. It is 2.5.8 you can download 2.6.3 here is the link ::::....http://javatutorialspoint.blogspot.com/2012/02/import-ksoap-into-android-project-in.html

      Delete
  9. what kind of ksoap jar did you use?

    ReplyDelete
  10. Hi chathura,
    It was nice tutorial.I have followed all the steps(Java webservices/Axis2+android).I tested with webservice testclient.java,it was working run as java application.
    But from android i can see defalut string hello world instead of web service message ie:hell chatura

    please explain

    ReplyDelete
    Replies
    1. You can't access the web service described in my "Create java web service with client using Axis2 & Eclipse" post in the same way demonstrated here. This application is to access the web service without sending any parameters to the web service. I have added the sample web service at the top of the post. If you need to send parameters from Android check my this post:::...
      http://codeoncloud.blogspot.com/2012/04/android-web-service-access-tutorial.html

      Delete
  11. Free ebook to download from 1000s of Programming,Laguages Engineering Medical Science Technology Windows Certification Dictionaries Magazines Business Free eBooks Rapidshare eBook Megaupload eBooks Free ebook.

    ReplyDelete
  12. I have a huge problem, and it would be appriated if someone can help or direct me to a solution. The problem is when my java code uses ksoap2 to pass a value to .net webservice to a webmethod, the methods parameters are null.

    I need this solution so I can use the app in a project for my final year.

    ReplyDelete
  13. Hi Chathura... Thanx for ur detailed explanation. Ur tutorial is very helpful. :)I am able to invoke webservice alone in java. But I want to access it from android application. How to do it??? second
    As u said "To set the service Right click on your project and select Run As >> Run on Server. Click next & click Finish" but when I right click on android project i dont find run on server.... :(. I find it as Run As>> Android Application. could u please help me out. when I launch emulator I am getting following error..
    "the application AndroidWS(process com.android.ws) has stopped unexpectedly. please try again."

    ReplyDelete
  14. Hi Chathura.. Thanx for ur detailed explaination. Ur tutorial is very helpful. :)
    I am able to invoke webservice alone from java application. But how to invoke it from android application???????? Second, As u said "To set the service Right click on your project and select Run As >> Run on Server. Click next & click Finish." but i couldnt find Run on server option. For android application we get option as Run as>> Android Application. when i launch emulator i am getting following error..
    the application AndroidWS(process com.android.ws) has stopped unexpectedly. please try again. Could u please help me out.. Thanx in advance

    ReplyDelete
  15. Thanks Chathura. Very helpful tutorial. Much appreciated.

    ReplyDelete
  16. Could you please tell me how to pass parameters for the method?

    ReplyDelete
  17. Hi,
    I am trying to consume webservice using java in android app. I am getting some error.

    THIS IS MY WEBSERVICES:

    definitions targetNamespace="http://tempuri.org/type" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdlns="http://tempuri.org/wsdl/" xmlns:typens="http://tempuri.org/type"
    element name="logon"
    complexType
    sequence
    element name="username" type="xsd:string" /
    element name="password" type="xsd:string" /
    /sequence
    /complexType
    /element
    portType name="WebServiceSoapPort"
    operation name="logon"
    input message="typens:logonrequest" /
    output message="typens:logonresponsetype" /
    /operation

    binding name="WebServiceSoapBinding" type="typens:WebServiceSoapPort"
    soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /
    operation name="logon"
    soap:operation soapAction="" / //It was empty
    input
    soap:body parts="parameters" use="literal"
    /input
    output
    soap:body use="literal"
    /output
    /operation
    service name="WebService"
    port name="WebServiceSoapPort" binding="typens:WebServiceSoapBinding"
    soap:address location="http://raja:90/CRM7/eware.dll/WebServices/SOAP"
    /port
    /service
    /definitions

    THIS IS MY ANDROID CODE:

    package com.example.ws1;
    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.PropertyInfo;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapPrimitive;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpTransportSE;

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

    public class MainActivity extends Activity
    {
    private static final String SOAP_ACTION = “http://tempuri.org/logon”;
    private static final String METHOD_NAME = “logon”;
    private static final String NAMESPACE = “http://tempuri.org/type”;
    private static final String URL = “http://192.168.7.86:90/CRM7/eware.dll/webservices.wsdl”;
    TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tv=(TextView)findViewById(R.id.text1);
    call();
    }
    public void call()
    {
    try {

    PropertyInfo pi = new PropertyInfo();
    pi.setName(“username”);
    pi.setValue(“admin”);
    pi.setName(“password”);
    pi.setValue(“test@123?);

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty(pi);
    //request.addAttribute(“username”, “admin”);
    //request.addAttribute(“password”, “test@123?);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.setAddAdornments(false);
    envelope.dotNet=true;
    envelope.setOutputSoapObject(request);

    HttpTransportSE androidHttpTransports = new HttpTransportSE(URL);
    androidHttpTransports.call(SOAP_ACTION, envelope);

    SoapObject response = (SoapObject) envelope.bodyIn;
    String results = response.getProperty(0).toString();
    //Object result = (Object)envelope.getResponse();

    tv.setText(results.toString());
    } catch (Exception e) {
    tv.setText(e.getMessage());
    }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
    }
    }

    I am calling the method “logon” and passing the parameter as ‘username’ and ‘password’
    after calling that function I am getting an error

    org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG @4:81 in java.io.InputStreamReader@4052e620)

    I just try to comment the below line also getting same error:
    envelope.dotNet=true;

    Please any one help on this..!

    Regards,
    Raja M

    ReplyDelete
  18. Hi,

    I'm new to Android, I tried run this program but I'm getting an exception of "java.lang.NoClassDefFoundError: org.ksoap2.serialization.SoapObject" & where to find the WSDL file, could you please explain?

    ReplyDelete
  19. In my eclipse i configured apache tomcat and axis 2 and server is present in servers tab. But when i start server following errors appear in console and message appears HTTP not found, please give me steps how to run it properly.Do i need to install anything else:

    org.apache.catalina.core.AprLifecycleListener init
    INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre7\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files/Java/jre7/bin/client;C:/Program Files/Java/jre7/bin;C:/Program Files/Java/jre7/lib/i386;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\eclipse;;.
    Oct 12, 2012 7:59:50 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
    WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:First' did not find a matching property.
    Oct 12, 2012 7:59:50 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["http-bio-9080"]
    Oct 12, 2012 7:59:50 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["ajp-bio-9009"]
    Oct 12, 2012 7:59:50 PM org.apache.catalina.startup.Catalina load
    INFO: Initialization processed in 888 ms
    Oct 12, 2012 7:59:50 PM org.apache.catalina.core.StandardService startInternal
    INFO: Starting service Catalina
    Oct 12, 2012 7:59:50 PM org.apache.catalina.core.StandardEngine startInternal
    INFO: Starting Servlet Engine: Apache Tomcat/7.0.32

    ReplyDelete
  20. Your blogs and information attracts me to come back again n again.
    one click root

    ReplyDelete
  21. Hi Chathura, this example I able to run in my emulator. Thanks for the tutorial. But is there any way to connect my android device to the web service that run in local server?

    ReplyDelete
  22. Hi Chathura, this example I able to run in my emulator. Thanks for the tutorial. But is there any way to connect my android device to the web service that run in local server?

    ReplyDelete
  23. Hi Chathura, this example I able to run in my emulator. Thanks for the tutorial. But is there any way to connect my android device to the web service that run in local server?

    ReplyDelete
  24. Web Designing
    ABC Technologies is a software and web site design company, offering you a comprehensive solution for your business. As an entrepreneur, you only think about your business venture and leave everything to us. Regardless of location, we make sure that we adjust to your desired working schedule. Why spend more if you can get the same quality, productivity and performance from an offshore partner.

    ReplyDelete
  25. Thank you.
    I lost a lot of days trying to develop an android client consuming an axis2 web server,
    and now,
    really,
    I see the light.
    Thank you very much.

    ReplyDelete

Chathura's Blog