Web Services and Service Oriented Computing has revolutionized the internet in the past decade. It is quite true that without web services most Apps in the App Store will be severely limited in their functionality be not be interesting at all. In this tutorial, you will learn how to use a RESTful web service for your Android App. This web service returns XML payload as the response to our request.
We'll be using the FREE web service provided by the website Webservices.net. This particular web service let's access the current price of a Stock based on its trading symbol.
Step 1: Know the Web Service
Before calling any web service, we must know how to call it and what you will get in response. This web service is a RESTful service so calling it is easy using a GET request.
GET /stockquote.asmx/GetQuote?symbol=string HTTP/1.1
Host: www.webservicex.net
The request requires a single input parameter, the stock symbol. For example, AAPL is the stock ticker symbol for Apple Inc. and MSFT is for Microsoft. If we send a request like the following through a browser:
www.webservicex.net/stockquote.asmx/GetQuote?symbol=AAPL
We should get the following output:
<string>
<StockQuotes>
<Stock>
<Symbol>AAPL</Symbol>
<Last>500.00</Last><Date>1/18/2013</Date><Time>4:00pm</Time>
<Change>-2.68</Change><Open>498.00</Open><High>502.22</High>
<Low>496.40</Low><Volume>16898180</Volume><MktCap>470.3B</MktCap>
<PreviousClose>502.68</PreviousClose>
<PercentageChange>-0.53%</PercentageChange><AnnRange>419.55 – 705.07</AnnRange>
<Earns>44.15</Earns><P-E>11.39</P-E><Name>Apple Inc.</Name>
</Stock>
</StockQuotes>
</string>
Step 2: Create the app
So just open your Eclipse IDE, create a new Android project and follow the wizard. If you are using Android Studio, then follow that requires steps accordingly.
Step 3: The Manifest
Since we will be accessing an external web service, we have to request the permission from the user before the app can invoke this web service over the internet. So add the following permission within the manifest tag of your app manifest file:
<uses-permission android:name=“android.permission.INTERNET” />
Without this permission, the app will not be able to reach out to the web service.
Step 4: Create the view
Now, create a view with the following three components:
- An EditText control to enter the ticker symbol.
- A Button to perform the task.
- A TextView to display the stock symbol value.
The XML for the view should look like this:
<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=“.ChooseSymbolActivity” >
<TextView
android:id=“@+id/textView1”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignBottom=“@+id/editText1”
android:layout_alignParentLeft=“true”
android:layout_alignTop=“@+id/editText1”
android:text=“Enter Ticker Symbol” />
<EditText
android:id=“@+id/editText1”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_alignParentTop=“true”
android:layout_marginTop=“36dp”
android:layout_toRightOf=“@+id/textView1”
android:ems=“10” >
<requestFocus />
</EditText>
<Button
android:id=“@+id/button1”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_below=“@+id/textView1”
android:layout_centerHorizontal=“true”
android:layout_marginTop=“36dp”
android:text=“@string/butText” />
<TextView
android:id=“@+id/textView2”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_below=“@+id/button1”
android:layout_centerHorizontal=“true”
android:layout_marginTop=“53dp”
android:text=“@string/soon” />
</RelativeLayout>
And the UI view itself should look like this:
Step 5: Call the web service
In this step, we will call the web service, parse the response and display the result. So go ahead and create a helper class which can call this service and returns various values. Initially, we'll only add the basic getters and setters for the fields we want to display.
package com.example.tickstock;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xmlpull.v1.XmlPullParser;
import android.util.Xml;
public class StockServiceHelper {
String symbol;
double last;
String name;
java.util.Date curDate;
HttpResponse httpResponse;
//the base url of the web service
static String baseUrl=“http://www.webservicex.net/stockquote.asmx/GetQuote?symbol=”;
public StockServiceHelper(String symbol) {
super();
this.symbol = symbol;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public double getLast() {
return last;
}
public void setLast(double last) {
this.last = last;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public java.util.Date getCurDate() {
return curDate;
}
public void setCurDate(java.util.Date curDate) {
this.curDate = curDate;
}
}
Now, we need to add two functions:
- A function to call the service itself.
- A function to parse the XML response.
The first function is as follows:
public void callService()
{
HttpClient client=new DefaultHttpClient();
HttpGet httpget = new HttpGet(baseUrl+symbol);
int responseCode=0;
String message;
String response;
try
{
httpResponse = client.execute(httpget);
responseCode = httpResponse.getStatusLine().getStatusCode();
message = httpResponse.getStatusLine().getReasonPhrase();
readresponse();
}
catch (Exception e)
{
}
}
Now, in order to parse the response received from the first step, we will get the handle to the Input Stream of the response. Further, we will parse the input stream using Android’s XML Pull Parser to extract the values from the various response tags.
private void readresponse() {
HttpEntity entity = httpResponse.getEntity();
try {
if (entity != null) {
InputStream instream = entity.getContent();
// read the stream
String innerXml = new String();
XmlPullParser parser = Xml.newPullParser();
// auto-detect the encoding from the stream
parser.setInput(instream);
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String name = null;
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
System.out.println(“start document”);
break;
case XmlPullParser.START_TAG:
name = parser.getName();
innerXml=parser.nextText();
break;
case XmlPullParser.END_TAG:
break;
}
eventType = parser.next();
}
parser=Xml.newPullParser();
parser.setInput(new StringReader(innerXml));
System.out.println(innerXml);
eventType=parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String name = null;
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
name = parser.getName();
if (name.equalsIgnoreCase(“last”)) {
this.setLast(Double.parseDouble(parser.nextText()));
} else if (name.equalsIgnoreCase(“date”)) {
Date x = new Date(parser.nextText());
this.setCurDate(x);
} else if (name.equalsIgnoreCase(“name”)) {
this.setName((parser.nextText()));
}
break;
case XmlPullParser.END_TAG:
break;
}
eventType = parser.next();
}
instream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Now all that remains is to call this helper function from our main application activity.
Step 6: Add the Event Handler
Let's now add an event handler for the button in our activity and call the web service when the button is clicked. To add an event handler, we have to first edit the button in the XML layout and an add event listener like this:
<Button
android:id=“@+id/button1”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_below=“@+id/textView1”
android:layout_centerHorizontal=“true”
android:layout_marginTop=“36dp”
android:text=“@string/butText”
android:onClick=“onBtnClicked” />
Since calling a web service requires access to the internet, we have to do this task as an AsyncTask. So let's add as AsyncTask implementation as an inner class within our activity class.
private class ContactWebservice extends AsyncTask<StockServiceHelper, Void, String> {
@Override
protected String doInBackground(StockServiceHelper… params) {
params[0].callService();
return “Price for “+params[0].getName()+” is “+params[0].getLast();
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.textView2);
txt.setText(result);
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void… values) {
}
}
Now we need to implement a particular event handler in our activity class called ChooseSymbolActivity. The handler will first check if the EditText contains a value(symbol) or not before calling the AsyncTask that we created above.
public void onBtnClicked(View v) {
if (v.getId() == R.id.button1) {
// handling the click now
EditText sym = (EditText) findViewById(R.id.editText1);
TextView tv = (TextView) findViewById(R.id.textView2);
if (sym.getText().toString().equalsIgnoreCase(“”)) {
tv.setText(“Enter Symbol!!”);
} else {
symbol = sym.getText().toString();
helper = new StockServiceHelper(symbol);
new ContactWebservice().execute(helper);
}
}
}
And here is the final output as shown below:
The complete source code for the app is attached below: