In this post I’m going to explain how would you consume a WCF service published on IIS on your local machine from an Android app on a device connected to local WiFi.
Before we start 3 prerequisites are needed:
- Basic knowledge of Android development.
- Knowledge of WCF services and SOA architecture.
- Basic knowledge of JSON data interchange protocol and format.
HOWEVER, I always believe in upside knowledge gain in software development; just try to code something even of you don’t understand much about .. you’ll get the big picture later.
Let’s start!
- The service:
The service we’re building is a very simple one. It will provide some data about people ( just ID’s and Names).
- Create a WCF Service application on Visual Studio call it “PersonsService”.
- We’re using REST module for building our service so on the Web.config file, remove the <system.serviceModel> tag with all of it’s contents.
- Right click on PersonsService.svc –> View Markup and add the following line to the <servicehost> tag:
Factory ="System.ServiceModel.Activation.WebServiceHostFactory"
Congratulations we now have a REST service, let’s start to make it useful for anything!
On IPersonsService.cs, you’ll find the Interface which will expose our methods and a class which acts as a data contract:
Rename the class to Person, remove the existing fields and add ID and Name Fields. It should look like this:
[DataContract] public class Person { int id; string name; [DataMember] public int ID { get { return id; } set { id = value; } } [DataMember] public string Name { get { return name; } set { name = value; } } }
Next, clean everything at the interface “IPersonService” and add a GetPersonsDataJSON() method that returns a list of persons:
[ServiceContract] public interface IPersonService { [WebGet(UriTemplate="/personsdataJSON", ResponseFormat=WebMessageFormat.Json)] [OperationContract] List GetPersonsDataJSON(); }
Notice the “WebGet” annotation above the method, this actually says 2 things:
- ResponseFormat=WebMessageFormat.Json: which means that we would like to use the JSON protocol for exchanging the data between our service and our client.
- UriTemplate=”/personsdataJSON”: means that the data formatted in JSON will be under the /personsdataJSON.
If we needed to provide data in XML format for some reason instead, we would add a new method to the IPersonService interface called GetPersonsDataXML() with UriTemplate=”/personsdataXML” & ResponseFormat=WebMessageFormat.XML.
One step for the end, on PersonService.svc.cs inherit the IPersonsService and implement the GetPersonsDataJSON method. Should look like this:
public class PersonService : IPersonService { public List GetPersonsDataJSON() { Person p1 = new Person(); p1.ID = 1; p1.Name = "Mina"; Person p2 = new Person(); p2.ID = 2; p2.Name = "John"; Person p3 = new Person(); p3.ID = 3; p3.Name = "Paula"; List persons = new List(); persons.Add(p1); persons.Add(p2); persons.Add(p3); return persons; } }
And the service is ready!
- Publishing on IIS:
This should be the easiest part: Right click on your project –> Properties –> Web –> select Use Local IIS Web Server and make sure Use IIS Express is unmarked then press Create Virtual Directory:
Note: You should be running Visual Studio as Administrator to be able to create the publish the service on IIS.
Now open IIS Manager, the service should be under Sites/Default Web Site .. Right click on it –> Manage Application –> Browse. You should see your project listing opened on your browser. Add /PersonService.svc/personsdataJSON to the path, so it should be:
http://localhost/PersonService/PersonService.svc/personsdataJSON
And the data should be returned on JSON format:
Note: Make sure to grant full control permission for IIS_IUSRS on the Web.config from properties & also on the PersonsService application on IIS through: Right click –> Edit Permissions –> Security tab.
- The Client:
UI: Well this is just a simple example to prove the concept, so let’s keep it simple. Here are the views:
- Place a list view that displays names.
- A button titled “Get Data”.
- A TextView as a title for the list.
It should look something like this:
As for the client logic there are 3 main components:
- Initialization
- Getting the data
- Extending AsyncTask to work asynchronously
1- Initialization:
- We need to initialize an instance of HttpClient which will help us to execute HttpGet which holds the service URL which returned the data previously when we ran it on browser.
- An instance or JSONObject which will hold the returned data.
- A string for the URL of the service
HttpClient client; final static String URL = "http://192.168.1.6/RPersonService/PersonService.svc/personsdata"; JSONObject json;
Inside the onCreate method place:
client = new DefaultHttpClient();
2- Getting the Data:
Now add another method and call it getPersonsData(). This method will do the following:
- Create an instance of HttpGet and give it the URL of the service.
- Use the HttpClient we created to execute HttpGet and return a response.
- Check the response status if it’s success, then starts filling the data in a JSONArray and returns it.
Code:
public JSONArray getPersonsData() throws ClientProtocolException, IOException, JSONException { HttpGet get = new HttpGet(URL); HttpResponse response = client.execute(get); int status = response.getStatusLine().getStatusCode(); if(status == 200) //sucess { HttpEntity e = response.getEntity(); String data = EntityUtils.toString(e); JSONArray personsData = new JSONArray(data); return personsData; } else { Toast.makeText(this, "error", Toast.LENGTH_SHORT); return null; } }
3- Extending AsyncTask to work asynchronously:
Add a new class called ReadData and set it to extend AsyncTask class. AsyncTask class let’s us generically specify the data structure we’re going to convert the JSONarray to, here we’ll use an ArrayList<String>.
Code:
public class ReadData extends AsyncTask<String, Integer, ArrayList> { @Override protected void onPostExecute(ArrayList data) { ArrayAdapter arrayAdapter = new ArrayAdapter(getApplicationContext(),android.R.layout.simple_list_item_1, data); lstView.setAdapter(arrayAdapter); super.onPostExecute(data); } @Override protected ArrayList doInBackground(String... params) { try { JSONArray personsNames = getPersonsData(); ArrayList persons = new ArrayList(); for(int i=0; i< personsNames.length(); i++) { persons.add(personsNames.getJSONObject(i).getString("Name")); } return persons; } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
ReadData class contains two overridden functions:
- doInBackground: Will call the getPersonsData and encapsulates the returned JSON data into an ArrayList<String>
- onPostExecute: Will take the ArrayList<String> formatted data and place it in the UI (ListView).
Notice that the returned data type from doInBackground must match with the data type of the parameter passed to the OnPostExecute method.
At the button click event of button Get Data we will use the ReadData class as follows:
new ReadData().execute();
One last thing, on AndroidManifest.xml add this line which will give permission to the app to use the internet/WiFi:
<uses-permission android:name="android.permission.INTERNET"/>
Now disable your Windows firewall, Run & press Get Data!:
Happy Coding! 🙂
Hi,
I am new on Android Development, and this is my newbie question: how can the ReadData class accesses to lstView which is defined into MainActivity.java?
Hi Mina,
The return value List is a List of what? This won’t compile unless it is is a List of something like List.
thanks
The type of list must be Person.
Hi this is great but if possible could you please solution of WCF ?
How about posting some search criteria to wcf service? Could you give us an example about that?
Thank you in advance.
thanks it worked
Can u please provide HttpURLConnection example ??
i have a question…..
question about IP address which is provide in URL can u explain that IP of Computer or or Emulater? how can get please explain this
thanks in advance
https://stackoverflow.com/questions/30144125/android-error-retrieving-data-from-wcf-webservice-java-net-socketexception-re
Any help here?
Hi i m vikram i devloped android app using asp.net wcf service . the hoe to call wcf service to
android please help me
I need return type to be string value to display in Edit text. Can you please put changes for this.
i have a question…..
question about IP address which is provide in URL can u explain that IP of Computer or or Emulater? how can get please explain this
thanks in advance
Hey I got error when pressiing GetData. Error Occours in PostExecute. Can i have the Solution for this..