Sunday, January 19, 2014

How to use WCF service in Android?

      This tutorial about the Rest - WCF service usage in android. WCF is a tool often used to implement and deploy a service-oriented architecture (SOA). It is designed using service-oriented architecture principles to support distributed computing where services have remote consumers. Clients can consume multiple services; services can be consumed by multiple clients. Services are loosely coupled to each other.WCF supports XML, JSON and ATOM data formats. It faster than ASMX and supports scaling/load balance.We use mostly GET, POST, PUT and DELETE methods.

GET Method:

The HTTP GET method is used to retrieve/read a representation of a resource.

Sample Data Format:
The sample JSON data is below.
[{"CountryID":1,"CountryName":"Andorra"},{"CountryID":2,"CountryName":"United Arab Emirates"},{"CountryID":3,"CountryName":"Afghanistan"},{"CountryID":4,"CountryName":"Antigua and Barbuda"},{"CountryID":5,"CountryName":"Anguilla"},{"CountryID":6,"CountryName":"Albania"},{"CountryID":7,"CountryName":"Armenia"},{"CountryID":8,"CountryName":"Netherlands Antilles"},{"CountryID":9,"CountryName":"Angola"},{"CountryID":10,"CountryName":"Antarctica"},{"CountryID":11,"CountryName":"Argentina"},{"CountryID":12,"CountryName":"American Samoa"},{"CountryID":13,"CountryName":"Austria"},{"CountryID":14,"CountryName":"Australia"},{"CountryID":15,"CountryName":"Aruba"},{"CountryID":16,"CountryName":"Azerbaijan"},{"CountryID":17,"CountryName":"Bosnia and Herzegovina"},{"CountryID":18,"CountryName":"Barbados"},{"CountryID":19,"CountryName":"Bangladesh"},{"CountryID":20,"CountryName":"Belgium"}]

Code:
      Now, read the data from server with simple HTTP Request and display the results with the help of  Lazy Adapter.
     We have to use StrictMode.ThreadPolicy method here. Because, the network operations (HTTPUrlConnections, HttpClients) can't executed on UI thread. So, we are using StrictMode.ThreadPolicy. We will get the NetworkOnMainThreadException on done.


  StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
  StrictMode.setThreadPolicy(policy);


Http Request:

Make a HTTP request to get/read the data from the WCF Service.    
 try{

ArrayList<HashMap<String, String>> CountriesList = new ArrayList<HashMap<String, String>>();
String SURL= "http://tejaprakash.com/restservice/Service.svc/GetCountries";
InputStream in = null;
String serviceResult = "";
              //Assign your URL here
URL url = new URL(SURL);
             
HttpURLConnection urlConn = (HttpURLConnection) url
.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.connect();

in = httpConn.getInputStream();

                //Read the response
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int read = 0;
int bufSize = 512;
byte[] buffer = new byte[bufSize];
while (true)
{
read = bis.read(buffer);
if (read == -1)
{
break;
}
baf.append(buffer, 0, read);
}
                //Get your result here.
serviceResult = new String(baf.toByteArray());
Log.v("serviceResult", serviceResult);

                //Making list.
JSONArray array = new JSONArray(serviceResult.trim());
for (int i = 0; i < array.length(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();

JSONObject object = (JSONObject) array.get(i);

map.put(KEY_CountryId,object.getString("CountryID"));
map.put(KEY_CountryName, object.getString("CountryName"));

CountriesList.add(map);
}
list=(ListView)findViewById(R.id.listview);
adapter=new LazyAdapter(WcfServiceActivity.this, CountriesList);      
                list.setAdapter(adapter); //Setting data to Adapter.
}
catch(Exception e){  }

Working with Lazy Adapter :


       public class LazyAdapter extends BaseAdapter {
public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
       activity = a;
       data=d;
       inflater =                                                                                                                                                 (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     
   }

   public int getCount() {

       return data.size();
   }

   public Object getItem(int position) {

       return position;
   }

   public long getItemId(int position) {

       return position;
   }
 
   public View getView(int position, final View convertView, ViewGroup parent) {
       View vi=convertView;
       if(convertView==null)
         vi = inflater.inflate(R.layout.wcf_samplelist, null);

     

       TextView country = (TextView)vi.findViewById(R.id.country);
      
       HashMap<String, String> Clist = new HashMap<String, String>();
       Clist = data.get(position);
      
       country.setText(Clist.get(WcfServiceActivity.KEY_CountryId)+".                                                                                                                "+Clist.get(WcfServiceActivity.KEY_CountryName));

       return vi;
   }
}

Full Code:
     I have created two layouts named ''wcf_sample'' and ''wcf_samplelist''. First one is main layout view and another is inflate. Follow the code below.

wcf_sample.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <TextView
            android:id="@+id/textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
           android:text="WCF Sample data"
            android:textSize="25sp"/>

        <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:padding="20dp"
        android:layout_marginTop="10dp"/>
 
</LinearLayout>

wcf_samplelist.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

   <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="NA"
        android:id="@+id/country"
       android:textStyle="bold"/>

</LinearLayout>

WcfServiceActivity:

package com.prakash_WCfDataUsage;

import java.io.BufferedInputStream;


import java.io.InputStream;


import java.net.HttpURLConnection;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.http.util.ByteArrayBuffer;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;

import android.content.Context;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ListView;
import android.widget.TextView;


public class WcfServiceActivity extends Activity {




static final String KEY_CountryId = "CountryID";
static final String KEY_CountryName = "CountryName";
private Activity activity;
        private ArrayList<HashMap<String, String>> data;
        ListView list;
LazyAdapter adapter;
 
    private static LayoutInflater inflater=null;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.wcf_sample);

StrictMode.ThreadPolicy policy = new                                 StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

 try{

ArrayList<HashMap<String, String>> CountriesList = new ArrayList<HashMap<String, String>>();
String SURL= "http://tejaprakash.com/restservice/Service.svc/GetCountries";
InputStream in = null;
String serviceResult = "";
              //Assign your URL here
URL url = new URL(SURL);
             
HttpURLConnection urlConn = (HttpURLConnection) url
.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.connect();

in = httpConn.getInputStream();

                //Read the response
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int read = 0;
int bufSize = 512;
byte[] buffer = new byte[bufSize];
while (true)
{
read = bis.read(buffer);
if (read == -1)
{
break;
}
baf.append(buffer, 0, read);
}
                //Get your result here.
serviceResult = new String(baf.toByteArray());
Log.v("serviceResult", serviceResult);

                //Making list.

JSONArray array = new JSONArray(serviceResult.trim());
for (int i = 0; i < array.length(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();

JSONObject object = (JSONObject) array.get(i);

map.put(KEY_CountryId,object.getString("CountryID"));
map.put(KEY_CountryName, object.getString("CountryName"));

CountriesList.add(map);
}
list=(ListView)findViewById(R.id.listview);
adapter=new LazyAdapter(WcfServiceActivity.this, CountriesList);      
                list.setAdapter(adapter); //Setting data to Adapter.
}

catch(Exception e){  }

}

public class LazyAdapter extends BaseAdapter {

public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
       activity = a;
       data=d;
       inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     
   }

   public int getCount() {

       return data.size();
   }

   public Object getItem(int position) {

       return position;
   }

   public long getItemId(int position) {

       return position;
   }
 
   public View getView(int position, final View convertView, ViewGroup parent) {
       View vi=convertView;
       if(convertView==null)
           vi = inflater.inflate(R.layout.wcf_samplelist, null);

     

       TextView country = (TextView)vi.findViewById(R.id.country);
     
     
     
       HashMap<String, String> Clist = new HashMap<String, String>();
       Clist = data.get(position);
     
     
       country.setText(Clist.get(WcfServiceActivity.KEY_CountryId)+". "+Clist.get(WcfServiceActivity.KEY_CountryName));
     
   
     
       return vi;
   }
}


Result screen:




POST Method:

    The HTTP POST is mostly used for creation of new resource. It simply submits data into specified resource.
We will post the data to server using HTTP POST in android.

Sample Data Post Format:
This is the sample format that we have to post/submit the data. And we are using below URL and format.




Code:

     We have to use HTTP POST method for creation of a new resource. Here, i am creating one JSON object and passing it in Post method.

try{
    //JSON Object created
   String json;
    JSONObject jobj = new JSONObject();
 
   //adding data to object
   // jobj.put("Address", address.getText().toString()); //assign your TextBox text directly!!
     jobj.put("Address", "Nncl Colony");
    jobj.put("Address2", "");
    jobj.put("City", "Hyderabad");
    jobj.put("CountryID", 45);
    jobj.put("Email","info@tejaprakash,com");
    jobj.put("FirstName", "teja");
    jobj.put("LastName", "Prakash");
    jobj.put("Phone", ""NA");
    jobj.put("StateID", 2);
    jobj.put("UserID", 1234);
    jobj.put("Zip", "500001");
 
    json = jobj.toString();
    Log.v("json",json.toString());
 
 
    StringEntity input = new StringEntity(jobj.toString(), HTTP.UTF_8);

HttpClient httpclient = new DefaultHttpClient();
//Add your URL here.  
HttpPost httppost = new                 HttpPost("http://tejaprakash.com/WcfRest_service/Service.svc/PostUserProfile?");

//Pass your json object
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
    nameValuePairs.add(new BasicNameValuePair("json",json ));

    httppost.setEntity(input);

   //Set the header content here.
    httppost.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=utf-8");
    HttpResponse response = httpclient.execute(httppost);
 
    //Read the Response
    BufferedReader reader = new BufferedReader(new
    InputStreamReader(response.getEntity().getContent(), "UTF-8"));
    StringBuilder builder = new StringBuilder();
    for (String line = null; (line = reader.readLine()) != null;)
    {
        builder.append(line).append("\n");
    }
 
    //Get the response!!
    String responseString= builder.toString();
    Log.v("response",responseString.toString());
   
   if(responseString.equals(true))
       {
    Toast.makeText(getApplicationContext(), "Profile Created Successfully ", 300).show();
   
       }
else
{
        //do something!!!!
}

}

catch(Exception e){ }


     On successful, you will get the response "true". Otherwise ''false''. The PUT and DELETE requests will be almost same as like POST and GET respectively.

Enjoy coding!!!

Read More »

Sunday, January 5, 2014

XML SAX Parsing in Android

     This tutorial explains you about the SAX parsing in Android. SAX (Simple API for XML) is an event-based sequential access parser API. SAX provides a mechanism for reading data from an XML document that is an alternative to that provided by the Document Object Model (DOM). Where the DOM operates on the document as a whole and takes more memory to store, SAX parsers operate on each piece of the XML document sequentially. Generally, SAX parsing is suitable more for large files.
Usually, Android applications need to call third-party service API's. We have so many data formats like json, xml, wddx, yaml, php, dump etc,. But we use mostly xml and json formats to transfer data.

XML Data Format:

XML was created to structure, store and transport data. It will be easily readable by the humans as well machines. Follow the sample XML format. I am saving this data named studentDetails.xml in  res/raw folder.

<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<no>1</no>
<name>sachin</name>
<class>Computers</class>
<phno>1234567890</phno>
<email>sachin@gmail.com</email>
</student>

<student>
<no>2</no>
<name>Ganguly</name>
<class>EEE</class>
<phno>1234567890</phno>
<email>Ganguly@gmail.com</email>
</student>

<student>
<no>3</no>
<name>Dravid</name>
<class>CSE</class>
<phno>1234567890</phno>
<email>Dravid@gmail.com</email>
</student>

<student>
<no>4</no>
<name>Laxman</name>
<class>CSIT</class>
<phno>1234567890</phno>
<email>Laxman@gmail.com</email>
</student>

<student>
<no>5</no>
<name>Kumble</name>
<class>MCA</class>
<phno>1234567890</phno>
<email>Kumble@gmail.com</email>
</student>

</students>



How to Parse XML data?

Now, we need to parse the above xml data in android. Follow the step by step process below.

First, Open or create your project.
Then, create an xml layout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:paddingLeft="10dp" >
  
  <TextView
  android:id="@+id/SNoText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />
  
  <TextView
  android:id="@+id/SNameText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:textStyle="bold" />
  
  <TextView
  android:id="@+id/SClassText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"/>
  
  <TextView
  android:id="@+id/SPhoneText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />
  
  <TextView
  android:id="@+id/SEmailText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />

</LinearLayout>



Now, start your activity code. Create an ListActivity named SaxParserDemoActivity. And follow the below code.



package com.prakash_saxparser;

import java.io.InputStream;

import java.util.ArrayList;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.app.Activity;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class SaxParserDemoActivity extends ListActivity {


      //Decalre String Arrays here

ArrayList<String> al_studentNo=new ArrayList<String>();
ArrayList<String> al_studentName=new ArrayList<String>();
ArrayList<String> al_studentClass=new ArrayList<String>();
ArrayList<String> al_studentPhno=new ArrayList<String>();
ArrayList<String> al_studentEmail=new ArrayList<String>();

SAXParserFactory spf;
SAXParser sp;
XMLReader xr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

try{
          //Getting student data from Raw folder here.
        InputStream is=getResources().openRawResource(R.raw.studentdetails);
               
        spf=SAXParserFactory.newInstance();
        sp=spf.newSAXParser();
        xr=sp.getXMLReader();
       
        MyHandler mh=new MyHandler();
        xr.setContentHandler(mh);
       
        xr.parse(new InputSource(is));
        }
        catch(Exception e){}
setListAdapter(new MyAdapter());
       
}

//Created Adapter class.

class MyAdapter extends BaseAdapter{

@Override

public int getCount() {
// TODO Auto-generated method stub
return al_studentClass.size(); 
}

@Override

public Object getItem(int arg0) {
// TODO Auto-generated method stub
return arg0;
}

@Override

public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}

@Override

public View getView(int arg0, View arg1, ViewGroup arg2) {
LayoutInflater li=(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View v=li.inflate(R.layout.saxlayout, null); //Applying layout.
//Setting data to layout.
TextView tv1=(TextView)v.findViewById(R.id.SNoText);
tv1.setText(al_studentNo.get(arg0));

TextView tv2=(TextView)v.findViewById(R.id.SNameText);
tv2.setText(al_studentName.get(arg0));

TextView tv3=(TextView)v.findViewById(R.id.SClassText);
tv3.setText(al_studentClass.get(arg0));

TextView tv4=(TextView)v.findViewById(R.id.SPhoneText);
tv4.setText(al_studentPhno.get(arg0));


TextView tv5=(TextView)v.findViewById(R.id.SEmailText);
tv5.setText(al_studentEmail.get(arg0));

return v;
}
   
    }
    //Creating MyHandler class.
    //starting......fill.......ending.....
    class MyHandler extends DefaultHandler{
    boolean is_studentNo=false;
    boolean is_studentName=false;
    boolean is_studentClass=false;
    boolean is_studentPhno=false;
    boolean is_studentEmail=false;
   
   
    @Override
    public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.startDocument();
    }
   
    @Override
    public void startElement(String uri, String localName, String name,
    Attributes attributes) throws SAXException {
    super.startElement(uri, localName, name, attributes);
    if(localName.equals("no")){
    is_studentNo=true;
    }
    else if(localName.equals("name")){
    is_studentName=true;
    }
    else if(localName.equals("class")){
    is_studentClass=true;
    }
    else if(localName.equals("phno")){
    is_studentPhno=true;
    }
    else if(localName.equals("email")){
    is_studentEmail=true;
    }
    }
   
    @Override
    public void characters(char[] ch, int start, int length)
    throws SAXException {
    // TODO Auto-generated method stub
    super.characters(ch, start, length);
    if(is_studentNo){
    al_studentNo.add(new String(ch,start,length));
    }
    else if(is_studentName){
    al_studentName.add(new String(ch,start,length));
    }
    else if(is_studentClass){
    al_studentClass.add(new String(ch,start,length));
    }
    else if(is_studentPhno){
    al_studentPhno.add(new String(ch,start,length));
    }
    else if(is_studentEmail){
    al_studentEmail.add(new String(ch,start,length));
    }
    }
   
    @Override
    public void endElement(String uri, String localName, String name)
    throws SAXException {
    // TODO Auto-generated method stub
    super.endElement(uri, localName, name);
   
    if(localName.equals("no")){
    is_studentNo=false;
    }
    else if(localName.equals("name")){
    is_studentName=false;
    }
    else if(localName.equals("class")){
    is_studentClass=false;
    }
    else if(localName.equals("phno")){
    is_studentPhno=false;
    }
    else if(localName.equals("email")){
    is_studentEmail=false;
    }
    }
   
    @Override
    public void endDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.endDocument();
    }
    }
}


Result screen:



How to get Web Service Data?
The above example shows you how to read stored file in application. But if you want to read the data from outside the application like web-services. Replace below code to above one.

//URL
String ServiceURL="http://10.0.12.1/MySampleService/Service.asmx/GetStudentData?UserID="+1;

spf=SAXParserFactory.newInstance();

      sp=spf.newSAXParser();
      xr=sp.getXMLReader();
      URL sourceUrl = new URL(ServiceURL);  
      MyHandler mh=new MyHandler();
      xr.setContentHandler(mh);
     
      xr.parse(new InputSource(sourceUrl.openStream()));

 Add internet permission in AndroidManifest.xml.

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

Enjoy coding!!!!!!!!!!

Read More »