Archive

Archive for the ‘Android’ Category

Android with WCF Services

March 1, 2012 24 comments

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
%d bloggers like this: