Home > Android, WCF > Android with WCF Services

Android with WCF Services

These days, android-based phones are gaining popularity and great apps are available and built every day to enhance its popularity. At this time, I want to work on android development and trying to find out how to communicate android with my existing application. The simplest way to do this is to expose the services to enable communication between android and my existing applications. In this blog post, I am going to look at how android can make use of WCF Services. But before moving forward, I would emphasize that since Android does not provide great support of XML or SOAP-based services, we are going to build WCF Restful Services responsible for providing response in JSON format. So, let’s start by looking first at how we can create WCF services.

I will begin by creating a WCF application named “EmployeeServices “with VS 2010 and deploy it on IIS Server. Although VS2010 provides us with a development server where we can test our services, Android will not be able to communicate withVS2010 Development Server, hence you would be required to deploy your services at IIS and with help from your local system IP address, provide DNS to Android.

Settings -> Wireless Control -> Mobile Networks -> Access Point Names, Select the active and replaced the proxy and port of your DNS

The Employee Entity is mention below

[DataContract]
public class Employee
{
[DataMember]
public int EmployeeId { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string BloodGroup { get; set; }
}

Here is the code of Contract and Services

[ServiceContract(Namespace = "http://services.example.com")]
public interface IEmployeeInfo
{
[OperationContract]
[WebGet(UriTemplate = "GetEmployee/?key={employeeId}" )]
Employee GetEmployee(int employeeId);
}

public class EmployeeInfo : IEmployeeInfo
{
public Employee GetEmployee(int employeeId)
{
Employee employeeInfo = GetEmployees().Where(employee => employee.EmployeeId == employeeId).FirstOrDefault();

return employeeInfo;
}

private List<Employee> GetEmployees()
{
return new List<Employee> {
new Employee { EmployeeId = 11, FirstName = "Waqas", LastName = "Yousuf", Address="A-175 Block 1" , BloodGroup = "B+" },
new Employee { EmployeeId = 22, FirstName = "Moiz", LastName = "Ahmed", Address="B-176 Block 2" , BloodGroup = "O-" },
new Employee { EmployeeId = 33, FirstName = "Waqas", LastName = "Raza", Address="C-177 Block 3" , BloodGroup = "A+" },
new Employee { EmployeeId = 44, FirstName = "Yasir", LastName = "Amin", Address="D-178 Block 4" , BloodGroup = "AB+" },
new Employee { EmployeeId = 55, FirstName = "Adeel", LastName = "Ali", Address="E-179 Block 5" , BloodGroup = "B+" },
new Employee { EmployeeId = 66, FirstName = "Fahad", LastName = "Ahmed", Address="F-180 Block 6" , BloodGroup = "B+" },
new Employee { EmployeeId = 77, FirstName = "Mahboob", LastName = "Ikram", Address="G-181 Block 7" , BloodGroup = "B+" },
new Employee { EmployeeId = 88, FirstName = "Saif", LastName = "Ali", Address="H-182 Block 8" , BloodGroup = "O+" },
new Employee { EmployeeId = 99, FirstName = "Nasir", LastName = "Saleem", Address="J-183 Block 9" , BloodGroup = "B+" },
new Employee { EmployeeId = 111, FirstName = "Yasir", LastName = "Shah", Address="I-184 Block 10" , BloodGroup = "O+" },
new Employee { EmployeeId = 222, FirstName = "Saad", LastName = "Usman", Address="J-185 Block 11" , BloodGroup = "B+" },
new Employee { EmployeeId = 333, FirstName = "Yaseen", LastName = "Wahid", Address="K-186 Block 12" , BloodGroup = "B+" },
new Employee { EmployeeId = 444, FirstName = "Qasim", LastName = "Wasi", Address="L-187 Block 13" , BloodGroup = "B+" },
new Employee { EmployeeId = 555, FirstName = "Asad", LastName = "Tamoor", Address="M-188 Block 14" , BloodGroup = "A+" },
new Employee { EmployeeId = 666, FirstName = "Idress", LastName = "Khan", Address="N-189 Block 15" , BloodGroup = "B+" },
new Employee { EmployeeId = 777, FirstName = "Rafa", LastName = "Rauf", Address="O-190 Block 16" , BloodGroup = "B+" },
new Employee { EmployeeId = 888, FirstName = "Fazain", LastName = "Farooq", Address="P-191 Block 17" , BloodGroup = "B+" },
new Employee { EmployeeId = 999, FirstName = "Ali", LastName = "Akber", Address="Q-192 Block 18" , BloodGroup = "B+" },
new Employee { EmployeeId = 1111, FirstName = "Irfan", LastName = "Khan", Address="R-193 Block 19" , BloodGroup = "B+" },
new Employee { EmployeeId = 2222, FirstName = "Omair", LastName = "Ali", Address="S-194 Block 20" , BloodGroup = "B+" },
new Employee { EmployeeId = 3333, FirstName = "Wasi", LastName = "Ahmed", Address="T-195 Block 21" , BloodGroup = "B+" },

};
}
}

Now here is the Code for Web.Config File.

<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint helpEnabled="true"
automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="EmployeeService.EmployeeInfo">
<endpoint kind="webHttpEndpoint"
contract="EmployeeService.IEmployeeInfo" />
</service>
</services>
</system.serviceModel>
</configuration>

In the WCF services I created an Employee Entity which has some employee information properties, and wrote a method which provides the collection of dummy data. You can replace it with your desired repository. To keep things simple, I am going to with simple approach. Next I created a contract in services named “GetEmployee” which is responsible to take the EmployeeID (at some places I refer to it as employee code) and if the matching employee exists the system will provide the complete entity of employee otherwise send it to blank. At the contract, annotate the URI Template,and I am creating an automated formatted service, which means that the same services will provide the data in form of XML or JSON based on the header information of the request. For further clarification, you may refer to one of my previous blog post. WCF 4.0 Automatic Formatting with Jquery Ajax.

Now the services are finalized and it’s time to move towards the Android side. For Android development, I have configured the required ADT plug-in, AVDand Android SDK in Eclipse IDE. Now, I am going to create Android Project named “EmployeeInfo” and click on Next button.

At this stage, I will select ‘Android 2.2’(Froyo)because as AVD I have configured Android 2.2

In the image below, you can find other information where Create Activity name is EmployeeInfoActivity.

Here is the code for EmployeeInfoActivity, in which I am using JSON Object to parse the JSON string I received from services. HttpGet has setter method of header, using which we can request the server for JSON data. Retrieve the data from the server and set them with TextView which are already placed at Android UI.

public class EmploeeInfoActivity extends Activity {

	private final static String EMPLOYEE_SERVICE_URI = "http://192.168.1.3/EmployeeService/EmployeeInfo.svc/GetEmployee/?key=";

	private EditText evEmployeeId;
private TextView tvEmployeeCode;
private TextView tvName;
private TextView tvAddress;
private TextView tvBloodGroup;
	private Button bSearchEmployee;
	private LinearLayout linearLayoutEmp;
	private LinearLayout linearLayoutError;

	/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

evEmployeeId = (EditText)findViewById(R.id.evEmployeeCode);

tvEmployeeCode = (TextView)findViewById(R.id.tvEmployeeCode);
tvName = (TextView)findViewById(R.id.tvEmployeeName);
tvAddress = (TextView)findViewById(R.id.tvAddress);
tvBloodGroup = (TextView)findViewById(R.id.tvBloodGroup);

linearLayoutEmp = (LinearLayout)findViewById(R.id.lLayoutEmployeeInfo);
linearLayoutError = (LinearLayout)findViewById(R.id.lLayoutError);

linearLayoutEmp.setVisibility(View.GONE);
linearLayoutError.setVisibility(View.GONE);
}

public void onSearchClick(View view)
{
try	{

	    	DefaultHttpClient client = new DefaultHttpClient();
	    	// http get request
	    	HttpGet request = new HttpGet(EMPLOYEE_SERVICE_URI + evEmployeeId.getText());

	    	// set the hedear to get the data in JSON formate
	    	request.setHeader("Accept", "application/json");
	        request.setHeader("Content-type", "application/json");

	        //get the response
	        HttpResponse response = client.execute(request);

	        HttpEntity entity = response.getEntity();

	        //if entity contect lenght 0, means no employee exist in the system with these code
	        if(entity.getContentLength() != 0) {
	        	// stream reader object
	        	Reader employeeReader = new InputStreamReader(response.getEntity().getContent());
		        //create a buffer to fill if from reader
	        	char[] buffer = new char[(int) response.getEntity().getContentLength()];
		        //fill the buffer by the help of reader
	        	employeeReader.read(buffer);
		        //close the reader streams
	        	employeeReader.close();

	        	//for the employee json object
		        JSONObject employee =  new JSONObject(new String(buffer));

		        //set the text of text view
		        tvEmployeeCode.setText("Code: " + employee.getString("EmployeeId"));
		        tvName.setText("Name: " + employee.getString("FirstName") + " " + employee.getString("LastName"));
		        tvAddress.setText("Address: " + employee.getString("Address"));
		        tvBloodGroup.setText("Blood Group: " + employee.getString("BloodGroup"));

		        //show hide layout
		        linearLayoutError.setVisibility(View.GONE);
		        linearLayoutEmp.setVisibility(View.VISIBLE);
	        }
	        else {
	        	 linearLayoutEmp.setVisibility(View.GONE);
	        	 linearLayoutError.setVisibility(View.VISIBLE);
	        }

}
catch (Exception e) {
//any exception show the error layout
linearLayoutEmp.setVisibility(View.GONE);
linearLayoutError.setVisibility(View.VISIBLE);
e.printStackTrace();
}

}
}

Now I am going to place control at layout.xml file for UI of the android, Search button is bound with onSearchClick event in EmployeeInfoActivity. One EditText, four TextView objects to display the employee information and if the employee information does not exist or garbage input, then it will display an error message.

After that, we have to put the internet permission in AndroidManifest.xml


<uses-permission android:name="android.permission.INTERNET" />

Now here are the final results:

Now if there is an error, error message(s) will  be displayed:

In this post, I just demonstrated how we can facilitate communication between Android and WCF services, using which we can easily perform all the CURD Operations. I hope you will enjoy the post and give your valuable feedback on it

Happy Coding 🙂

Advertisements
Categories: Android, WCF
  1. March 2, 2012 at 6:10 am

    Nice article… This is good for developers having experience on Microsoft platform and are working on Android clients.

  2. aamirhussain
    April 16, 2012 at 5:22 am

    i tried this example , but you do not have mention NAMESPACES to be used with both example ……

    please include this part too , so this would be more helpful for us……..

    thank you

  3. Vinod Kumar Gaur
    May 22, 2012 at 10:07 am

    Sir Please share me tutorials on Android bcz i am a beginner in Android.

    i will be greatful to you.

  4. aditya ingle
    June 27, 2012 at 9:00 pm

    sir can u help i creating wcf rerstful service for file uploading which can be consume on multiple platform like iphone, winforms, & android. plzzz

  5. Sanket
    August 10, 2012 at 8:02 am

    Hello, Waqas, i am getting error like android.os.NetworkOnMainThreadException while using you way of calling wcf service. I have test from direct URL , its working ! So now whats solution. Should i need to create a custom thread claass ??

  6. SHREYANS WAKEKAR
    August 27, 2012 at 12:39 pm

    which tool are you using for this example of android.?
    I m using VS2010 and installed mono for android. But getting some serious errors.!

    • Aqib
      January 14, 2014 at 10:03 pm

      start a seperate thread and perform network operation there, do not perform network operations in main ui thread, i.e in your main class , start a thread x= new thread() and in its run function perform operation there.

  7. Madiha
    September 29, 2012 at 8:04 pm

    can you please upload the code???

  8. Irakli
    October 1, 2012 at 8:28 am

    I have one question , can I browse that service in my browser ?
    I have errors:
    In PC browser : “500 – Internal server error.
    There is a problem with the resource you are looking for, and it cannot be displayed.”
    and during debug in android tab error is : “10-01 12:25:59.660: W/System.err(12322): java.net.SocketException: No route to host ”

    I’ve copied you web.config and I think problem is in it. Please help, I’ll be appreciate.

  9. Irakli
    October 1, 2012 at 8:44 am

    Now, I can browse that service in my PC browser, but when I want to browse exact method like this xxxx.xxx.xx.xx:82/EmployeeService/EmployeeInfo.svc/GetEmployee/?key=1 , HTTP 404 error is found and errror in eclipse is the same : java.net.SocketException: No route to host. Please help !

  10. paploy
    October 3, 2012 at 7:20 pm

    Do you any tutorial about how to deploy service to IIS?

  11. Razor
    October 6, 2012 at 3:00 pm

    can you upload project?I really need.

  12. Irakli
    October 8, 2012 at 5:59 am

    I corrected previous error, but now I have another problem. When I try to retrieve data using Entity Framework error is below:

    Error: Cannot obtain Metadata from http://localhost:52875/ControllersInfo.svc
    If this is a Windows (R) Communication Foundation service to which you have access,
    please check that you have enabled metadata publishing at the specified address.
    For help enabling metadata publishing, please refer to the MSDN documentation at
    http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error
    URI: http://localhost:52875/ControllersInfo.svc
    Metadata contains a reference that cannot be resolved:
    ‘http://localhost:52875/ControllersInfo.svc’.
    There was no endpoint listening at http://localhost:52875/ControllersInfo.svc that could accept the message.
    This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

    Can you tell me what is the problem ? without entity if works fine

  13. Eraj Fernando
    October 10, 2012 at 3:34 am

    This article saved me today. Very helpful. Thanks.

  14. Manoj
    October 15, 2012 at 11:02 am

    Sir, can you give the android part as a zip so that i can import and test it?

  15. May 30, 2013 at 9:22 am

    Hello,

    You can give the project for Download?

  16. Mathieu
    October 29, 2013 at 3:54 am

    Is this code working? Anyone?

  17. Muneeb
    December 15, 2013 at 6:43 am

    can you please Elaborate the proxy and port portion because I can’t get response from webservice.

  18. Muneeb
    December 15, 2013 at 6:45 am

    What IP address and PORT exactly it is ?

  19. millato
    December 18, 2013 at 12:24 pm

    it goes into the catch while i put the correct id 11

  1. October 11, 2012 at 5:13 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: