Posted by tech on
March 14, 2008
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
AndroidServiceConnection.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpURL;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.ksoap2.transport.ServiceConnection;
/**
* Connection using apache HttpComponent
*/
public class AndroidServiceConnection implements ServiceConnection {
private static HttpConnectionManager connectionManager = new SimpleHttpConnectionManager();
private HttpConnection connection;
private PostMethod postMethod;
private java.io.ByteArrayOutputStream bufferStream = null;
/**
* Constructor taking the url to the endpoint for this soap communication
* @param url the url to open the connection to.
*/
public AndroidServiceConnection(String url) throws IOException {
HttpURL httpURL = new HttpURL(url);
HostConfiguration host = new HostConfiguration();
host.setHost(httpURL.getHost(), httpURL.getPort());
connection = connectionManager.getConnection(host);
postMethod = new PostMethod(url);
}
public void connect() throws IOException {
if (!connection.isOpen()) { connection.open(); }
}
public void disconnect() { connection.releaseConnection(); }
public void setRequestProperty(String name, String value) { postMethod.setRequestHeader(name, value); }
public void setRequestMethod(String requestMethod) throws IOException {
if (!requestMethod.toLowerCase().equals(”post”)) { throw(new IOException(”Only POST method is supported”)); }
}
public OutputStream openOutputStream() throws IOException {
bufferStream = new java.io.ByteArrayOutputStream();
return bufferStream;
}
public InputStream openInputStream() throws IOException {
RequestEntity re = new ByteArrayRequestEntity(bufferStream.toByteArray());
postMethod.setRequestEntity(re);
postMethod.execute(new HttpState(), connection);
return postMethod.getResponseBodyAsStream();
}
public InputStream getErrorStream() { return null; }
}
AndroidHttpTransport.java
import java.io.*;
import org.ksoap2.transport.*;
import org.ksoap2.*;
import org.xmlpull.v1.*;
/**
* Apache HttpComponent based HttpTransport layer.
*/
public class AndroidHttpTransport extends Transport {
String response;
/**
* Creates instance of HttpTransport with set url
*
* @param url
* the destination to POST SOAP data
*/
public AndroidHttpTransport(String url) {
super(url);
}
/**
* set the desired soapAction header field
*
* @param soapAction
* the desired soapAction
* @param envelope
* the envelope containing the information for the soap call.
*/
public void call(String soapAction, SoapEnvelope envelope) throws IOException, XmlPullParserException {
if (soapAction == null) soapAction = “\”\”";
byte[] requestData = createRequestData(envelope);
requestDump = debug ? new String(requestData) : null;
responseDump = null;
ServiceConnection connection = getServiceConnection();
connection.connect();
try {
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”, “” + requestData.length);
connection.setRequestMethod(”POST”);
OutputStream os = connection.openOutputStream();
os.write(requestData, 0, requestData.length);
os.flush();
os.close();
requestData = null;
InputStream is;
try {
is = connection.openInputStream();
} catch (IOException e) {
is = connection.getErrorStream();
if (is == null) {
connection.disconnect();
throw (e);
}
}
//if (debug) {
ByteArrayOutputStream 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);
}
//}
parseResponse(envelope, is);
System.out.println(”—————-><"+envelope+"><<<");
System.out.println(”|—————->["+envelope.bodyIn +"]<<<");
System.out.println(”DBG:request:” + requestDump);
System.out.println(”DBG:response:” + responseDump);
} finally {
connection.disconnect();
}
}
protected ServiceConnection getServiceConnection() throws IOException {
return new AndroidServiceConnection(url);
}
}
Those are the two main classes that are vital for web service communication. This last code here will be your client Android app that will connect to the web service.
private static final String SOAP_ACTION = “method”;
private static final String METHOD_NAME = “method
private static final String NAMESPACE = “namespace”;
private static final String URL = “http://url/pathto/service/namespace”;
public static String mymethod() {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty(”whatever_name”, “whatever_value”);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
} catch (Exception e) {
e.printStackTrace();
}
}
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.
Like what you see? Buy me a cup of coffee. Or subscribe to my feeds. (1 votes, average: 5.00 out of 5)
Loading ...