Android m5 rc15 and Web services

Currently Google’s Android is under version m5 rc15. Instead of dabbling on converting all my java applet games to possibly android’s format, I focused on checking if Android is capable of calling web services or not. The answer is no. Android’s API doesn’t contain classes that support this capability.

However, a 3rd party library called KSoap2 is available for use. From their sourceforge website, “kSOAP is a SOAP web service client library for constrained Java environments such as Applets or J2ME applications (CLDC / CDC / MIDP)”. And how lucky that Android uses Java as its developmental language.

I am not sure if it is possible to build an Android application and call a remote web service by compiling it using a builder app like Ant. Most posts in the mailing list do cover making it work using the Eclipse IDE, as does most of Android’s tutorial focuses on.

I kept swarming the net looking for possible ways and solutions with using just Ant and not an IDE as i abhor using it. In the end, I had no choice but to use Eclipse to be able to at least verify that the sample code and solution provided by someone in the mailing list does indeed work.

Download the KSoap2 library. Extract the jar file library and add it in your Eclipse project. Create a lib folder and import the jar file there. Next, right click the project name and select properties. Under the Java Build Path, add the KSoap2 jar so that it will be included in the classpath during compilation and deployment. Click OK.

The following 2 files are needed for web service communication

The Android app code is pretty self explanatory. Just fill in the your values to the pre-defined variables. The request.addProperty() method is where you place your parameters in case the webservice method you want to call needs parameters supplied to it.

Requests will still be passed as XML. I hope this can help those who would want their Android apps to call webservices. I pretty had was stuck with this for probably a week browsing through the web, mailing lists or anything that I could come upon that would give me a hint as to how to make this work.

These codes were from someone in a mailing list who posted a solution. But I modified parts of it because they didn’t work in my case. Hit the run in the RUN menu of Eclipse to deploy your Android app. If you wish to see the System.out.println() messages in the console, run logcat. You won’t see those messages in the Eclipse console.

Related Posts Plugin for WordPress, Blogger...

7 comments

  1. Can you please tell me what I am doing wrong?

    I am receiving the following exception:

    SoapFault – faultcode: ‘soap:Client’ faultstring: ‘Server did not recognize the value of HTTP Header SOAPAction: CelsiusToFahrenheit.’ faultactor: ‘null’ detail: org.kxml2.kdom.Node@453807
    at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(Unknown Source)
    at org.ksoap2.SoapEnvelope.parse(Unknown Source)
    at org.ksoap2.transport.Transport.parseResponse(Unknown Source)
    at org.ksoap2.transport.AndroidHttpTransport.call(AndroidHttpTransport.java:80)
    at com.forpeepssync.Test2.main(Test2.java:30)

    Thanks, Adrian

    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.AndroidHttpTransport;

    public class Test2 {

    private static final String SOAP_ACTION = “CelsiusToFahrenheit”;
    private static final String METHOD_NAME = “CelsiusToFahrenheit”;
    private static final String NAMESPACE = “http://tempuri.org/”;
    private static final String URL = “http://www.w3schools.com/webservices/tempconvert.asmx?WSDL”;

    public static void main(String[] args) throws Exception {

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty(“Celsius”, “23”);
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.setOutputSoapObject(request);

    AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);

    androidHttpTransport.debug = true;

    try {
    androidHttpTransport.call(SOAP_ACTION, envelope);
    Object resultsRequestSOAP = envelope.getResponse();
    String[] results = (String[]) resultsRequestSOAP;
    System.out.println(results[0]);
    }
    catch (Exception aE) {
    aE.printStackTrace();
    ;
    }
    }
    }

  2. Hi

    I think the problem is with your soapaction, it should be as

    private static final String SOAP_ACTION = “http://tempuri.org/CelsiusToFahrenheit”

    The same problem is duscussed at

    click here

    Sincerely
    Ray

  3. I have 2 questions for you.

    Where should i place those 2 files we are creating?

    Do you have any idea in hoy to implement this in the 0.9 SDK Release??

    Thanks in advance for the help!

    Regards.

    Francisco Ortega

  4. hi fransisco

    i apologize but i stopped with android after i made that web service work so i have forgotten much about it.

    you could join googlegroups and ask your questions there. people will help

  5. I don’t agree with everything in this piece of content, but you do make some very good points. Im very interested in this subject matter and I myself do alot of research as well. Either way it was a well thoughtout and nice read so I figured I would leave you a comment. Feel free to check out my website sometime and let me know what you think.

  6. I guess now I am in the right place to ask the right question… so, really aspect your help..

    public class AndroidHttpTransport {

    String url;

    HttpURLConnection connection = null;
    OutputStream os;
    InputStream is;

    /** state info */
    private boolean connected = false;

    /** Set to true if debugging */
    public boolean debug;

    /** String dump of request for debugging. */
    public String requestDump;

    /** String dump of response for debugging */
    public String responseDump;

    /**
    * Creates instance of HttpTransport with set url and SoapAction
    *
    * @param url the destination to POST SOAP data
    * @param soapAction the desired SOAP action (for HTTP headers)
    */

    public AndroidHttpTransport(String url) {
    this.url = url;
    }

    /**
    * Set the target url.
    *
    * @param url the target url.
    */

    public void setUrl(String url) {
    this.url = url;
    }

    /**
    * set the desired soapAction header field
    *
    * @param soapAction the desired soapAction
    */

    public void call(String soapAction, SoapEnvelope envelope, String requestXML) throws IOException, XmlPullParserException {
    if (soapAction == null)
    soapAction = “\”\””;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    XmlSerializer xw = new KXmlSerializer();
    byte[] requestDataByte = requestXML.getBytes();

    URL url = new URL(ApplicationConstant.WEB_SERVICE_URL+ApplicationConstant.WEB_SERVICE_AUTHENTICATION_URI);
    System.out.println(“RequestDump—> “+new String(requestXML));
    requestDump = debug ? new String(requestXML) : null;
    responseDump = null;
    //ServiceConnection connection = getServiceConnection();
    System.out.println(“Insideconnection+++ block”+url);
    //connection.connect();

    try {
    URLConnection urlConnection = url.openConnection();
    is = new BufferedInputStream(urlConnection.getInputStream());
    System.out.println(“Inside the try block”);
    connection.setRequestProperty(“User-Agent”, “kSOAP/2.0”);
    connection.setRequestProperty(“SOAPAction”, soapAction);
    connection.setRequestProperty(“Content-Type”, “text/xml”);
    connection.setRequestProperty(“Connection”, “close”);
    connection.setRequestProperty(“Content-Length”, “” + requestDataByte.length);
    connection.setRequestMethod(“POST”);

    System.out.println(“after connection”);
    StringBuffer buff = new StringBuffer(ApplicationConstant.AUTH_USER_ID);
    buff.append(‘:’).append(ApplicationConstant.AUTH_PASSWORD);
    byte[] raw = buff.toString().getBytes();
    System.out.println(“after buff Auth_User_ID”);
    buff.setLength(0);
    buff.append(“Basic “);
    org.kobjects.base64.Base64.encode(raw, 0, raw.length, buff);
    connection.setRequestProperty(“Authorization”, buff.toString());
    System.out.println(“after Authorization kobjects”);
    os = connection.getOutputStream();
    System.out.println(“after os connection”);
    os.write(requestDataByte, 0, requestDataByte.length);
    System.out.println(“after os write”);
    os.flush (); // removed in order to avoid chunked encoding
    os.close();
    requestDataByte = null;
    System.out.println(“after request data”);
    InputStream is;
    try {
    System.out.println(“Inside IS connection.openInputStream();”);
    is = connection.getInputStream();
    } catch (IOException e) {
    System.out.println(“Exception is ” +e);
    is = connection.getErrorStream();
    if (is == null) {
    connection.disconnect();
    throw (e);
    }
    }
    if (debug) {
    bos = new ByteArrayOutputStream();
    byte[] buf = new byte[256];
    while (true) {
    int rd = is.read(buf, 0, 256);
    if (rd == -1)
    break;
    bos.write(buf, 0, rd);
    }
    bos.flush();
    buf = bos.toByteArray();
    responseDump = new String(buf);
    is.close();
    is = new ByteArrayInputStream(buf);
    if (debug) {
    System.out.println(“DBG:request:” + requestDump);
    System.out.println(“DBG:response:” + responseDump);
    }
    }

    } finally {
    connection.disconnect();
    }
    }

    protected ServiceConnection getServiceConnection() throws IOException {
    return new AndroidServiceConnection(url);
    }
    }

    From code you can understand that the xml file is being send.. with the authentication userId and password.. so, can you.. help me out.. for the execution of the code..l..

  7. @kamal: my code is very old.like 5 years ago when android was still in beta so i have forgotten about this. i hope someone else can help you though

Leave a Reply

Your email address will not be published. Required fields are marked *