Showing posts with label Android JSON currency convertor. Show all posts
Showing posts with label Android JSON currency convertor. Show all posts

Friday, December 20, 2013

Android JSON based Web Services tutorial

ANDROID JSON BASED WEB SERVICES TUTORIAL

JSON or JavaScript Object Notation is a lightweight  text-based open standard designed for human-readable data interchange. The JSON format was originally specified by Douglas Crockford, and is described in RFC 4627. The official Internet media type for JSON is application/json. The JSON filename extension is .json.
JSON syntax is similar to the  JavaScript syntax of java script objects, it includes the following:
              Data is represented in name/value pairs
        Curly braces hold objects and each name is followed by ':'(colon), the name/value pairs are separated by , (comma).
               Square brackets hold arrays and values are separated by ,(comma).
following provides  a simple example:
{
    "staff": [   
 {
       "staff_Id":"1",
       "dept": "IT",
       "specialization": "Computer Science",
       "name": "K.Navin"
    },
    {
       "staff_Id":"2",
       "dept": "CSE",
       "specialization": "Computer Science",
       "name": "V.Joseph Raymond"
    }, ]
}
Android JSON Parsers
            Android provides four differnet classes to manipulate JSON data. These classes areJSONArray,JSONObject,JSONStringer and JSONTokenizer.
JSON - Elements
An JSON file consist of many components. Here is the table defining the compoents of an JSON file and their description:

Sl.No
Component & description
1
Array([)
In a JSON file , square bracket ([) represents a JSON array
2
Objects({)
In a JSON file, curly bracket ({) represents a JSON object
3
Key
A JSON object contains a key that is just a string. Pairs of key/value make up a JSON object
4
Value
Each key has a value that could be string , integer or double e.t.c
JSON – Parsing
For parsing a JSON object, we will create an object of class JSONObject and specify a string containing JSON data to it. Its syntax is:
String in;
JSONObject reader = new JSONObject(in);
                           The last step is to parse the JSON. An JSON file consist of different object with different key/value pair e.t.c. So JSONObject has a seperate function for parsing each of the component of JSON file. Its syntax is given below:
ArrayList<HashMap<String, String>>staffList = new ArrayList<HashMap<String, String>>();
// Getting Array of staff details
                                    JSONObject saffs = json.getJSONArray(“staff”);
                                   
                                    // looping through All staff details
                                    for(int i = 0; i < staffs.length(); i++){
                                                JSONObject c = staffs.getJSONObject(i);
                                               
                                                // Storing each json item in variable
                                                Integer  id = c.getString(“staff_id”);
                                                String name = c.getString(“dept”);
                                                String email = c.getString(“specialization”);
                                                String address = c.getString(“name”);
// creating new HashMap
                                                HashMap<String, String> map = new HashMap<String, String>();
                                                // adding each child node to HashMap key => value
                                                map.put(“STAFF_ID”, id);
                                                map.put(“NAME”, name);
                                                map.put(“DEPARTMENT”, email);
                                                map.put(“SPECIALIZATION”, mobile);

                                                // adding HashList to ArrayList
                                                staffList.add(map);
                                       }
                                               
The method getJSONObject returns the JSON object. The method getString returns the string value of the specified key.
Apart from the these methods , there are other methods provided by this class for better parsing JSON files. These methods are listed below:
Sr.No
Method & description
1
get(String name)
This method just Returns the value but in the form of Object type
2
getBoolean(String name)
This method returns the boolean value specified by the key
3
getDouble(String name)
This method returns the double value specified by the key
4
getInt(String name)
This method returns the integer value specified by the key
5
getLong(String name)
This method returns the long value specified by the key
6
length()
This method returns the number of name/value mappings in this object..
7
names()
This method returns an array containing the string names in this object.

The Demonstrative project uses the JSON services from the following url to fetch currency rate between British pound,Indian rupees,U.S dollor and euro .http://www.rate-exchange.appspot.com 
1.Create  Android project with details as listed in the table below.
Property name
Property value
Project name
SRM_CurrencyConvertorJSON
Package name
in.ac.srmuniv.currencyconvertorjson
Activity name
MainActivity
Layout xml name
main.xml



2.Copy the code  to the file gridview.xml in res/layout folder 
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"
        android:text="@string/app_name"
        android:textSize="@dimen/headsize" />

    <TableLayout
        android:id="@+id/TableLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp" >

        <TableRow
            android:id="@+id/tableRow1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginLeft="10dp" >

            <Spinner
                android:id="@+id/spinner1"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:drawSelectorOnTop="true"
                android:prompt="@string/select_Category"/>
        </TableRow>

        <TableRow
            android:id="@+id/tableRow2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginLeft="10dp" >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:text="@string/to"
                android:textAppearance="?android:attr/textAppearanceMedium"/>
        </TableRow>

        <TableRow
            android:id="@+id/tableRow3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginLeft="10dp"
            android:gravity="center_horizontal" >

            <Spinner
                android:id="@+id/spinner2"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"/>
        </TableRow>

        <TableRow
            android:id="@+id/tableRow6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginLeft="10dp" >

            <Space android:layout_height="20dp"/>
        </TableRow>

        <TableRow
            android:id="@+id/tableRow3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginLeft="10dp" >

            <TextView
                android:id="@+id/textView3"
                style="@style/CodeFont"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Enter Value of money to be converted"/>
        </TableRow>
    </TableLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <EditText
            android:id="@+id/editText1"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="40dp"
            android:layout_marginLeft="10dp"
            android:inputType="numberDecimal"
            android:maxLength="4" />

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/convert" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView2"
            style="@style/CodeFont"
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal"
            android:text="Converted"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textSize="@dimen/out" />
    </LinearLayout>

</LinearLayout>
3.Copy the code  to the file row.xml in res/layout folder 
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="1dip" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/country"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dip"
        android:layout_toRightOf="@+id/image"
        android:padding="2dip"
        android:textColor="@drawable/red"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/currency"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/country"
        android:layout_marginLeft="5dip"
        android:layout_toRightOf="@+id/image"
        android:padding="2dip"
        android:textColor="@drawable/darkgrey" />


</RelativeLayout>
4.Copy the code in MainActivity.java. Activity.
packagein.ac.srmuniv.currencyconvertorjson;

importin.ac.srmuniv.currencyconvertorjson.R;
importandroid.app.Activity;
importandroid.app.ProgressDialog;
importandroid.content.Context;
importandroid.os.AsyncTask;
import android.os.Bundle;
importandroid.view.LayoutInflater;
import android.view.View;
importandroid.view.ViewGroup;
importandroid.widget.AdapterView;
importandroid.widget.AdapterView.OnItemSelectedListener;
importandroid.widget.ArrayAdapter;
import android.widget.Button;
importandroid.widget.EditText;
importandroid.widget.ImageView;
importandroid.widget.Spinner;
importandroid.widget.TextView;
importandroid.widget.Toast;

public class MainActivity extends Activity {
    String[] country = { "British", "European", "American", "Indian" };

    String[] currency = { "Pounds ", "Euro", "Dollor", "Rupee" };
    String[] currency_abr = { "GBP", "EUR", "USD", "INR" };
    String to_curr, from_curr;

    int arr_images[] = { R.drawable.pound, R.drawable.euro, R.drawable.dollor,
            R.drawable.rupee };
    TextView converted;
    Spinner from_currency;
    Spinner to_currency;
    EditText input;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        to_curr = "INR";
        from_curr = "USD";
        setContentView(R.layout.activity_main);
        converted = (TextView) findViewById(R.id.textView2);
        input = (EditText) findViewById(R.id.editText1);
        converted.setText("");

        from_currency = (Spinner) findViewById(R.id.spinner1);
        from_currency.setAdapter(newMyAdapter(MainActivity.this, R.layout.row,
                country));
        from_currency.setSelection(2);
        to_currency = (Spinner) findViewById(R.id.spinner2);
        to_currency.setAdapter(newMyAdapter(MainActivity.this, R.layout.row,
                country));
        to_currency.setSelection(3);
        from_currency.setOnItemSelectedListener(newOnItemSelectedListener() {

            public voidonItemSelected(AdapterView<?> parentView, View v,
                    int position, long id) {
                Toast.makeText(getApplicationContext(),
                        "" + currency_abr[position], Toast.LENGTH_LONG).show();
                converted.setHint(currency[position]);
                from_curr = currency_abr[position];

            }

            public voidonNothingSelected(AdapterView<?> parentView) {
                // your code here
            }

        });
        to_currency.setOnItemSelectedListener(newOnItemSelectedListener() {

            public voidonItemSelected(AdapterView<?> parentView, View v,
                    int position, long id) {
                Toast.makeText(getApplicationContext(),
                        "" + currency_abr[position], Toast.LENGTH_LONG).show();
                converted.setHint(currency[position]);
                to_curr = currency_abr[position];

            }

            public voidonNothingSelected(AdapterView<?> parentView) {
                // your code here
            }

        });

        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(newView.OnClickListener() {

            @Override
            public void onClick(View v) {

                newDownloadData().execute(to_curr, from_curr, input.getText()
                        .toString());
            }
        });

        converted = (TextView) findViewById(R.id.textView2);
    }

    class DownloadData extends AsyncTask<String, String, Double> {

        ProgressDialog pd = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pd = newProgressDialog(MainActivity.this);
            pd.setTitle("Converting...");
            pd.setMessage("Please wait...");
            pd.setCancelable(false);
            pd.show();

        }

        @Override
        protected Double doInBackground(String... params) {

            String to_curr = params[0];
            String from_curr = params[1];
            String value = params[2];
            // Creating JSON Parser instance
            JSONParser jParser = new JSONParser();
            // getting JSON string from URL

            jParser.getJSONFromUrl("http://www.currency-api.appspot.com /api/"+from_curr+"/"+ to_curr +".json");
           /*
jParser.getJSONFromUrl("http://www.rate-exchange.appspot.com/currency?from="
                    + from_curr + "&to=" + to_curr + "&q=" + value);not supported now

         
             * JSONObject json = jParser
             * .getJSONFromUrl("http://www.google.com/ig/calculator?hl=en&q=" +
             * value + from_curr + "=" + to_curr + "?"); //Google stopped
             * service from Nov 1 2013
             */
            double theResult = jParser.getResult();
            return theResult;
        }

        @Override
        protected void onPostExecute(Double theResult) {
            super.onPostExecute(theResult);
            pd.dismiss();
            /*
             * double x; try { x = Double.parseDouble(theResult); } catch
             * (NumberFormatException e) { // TODO Auto-generated catch block x
             * = 1; input.setText(""); }
             */
            converted.setText(theResult.toString());
        }
    }

    public class MyAdapter extendsArrayAdapter<String> {

        public MyAdapter(Context context, int textViewResourceId,
                String[] objects) {
            super(context, textViewResourceId, objects);
        }

        @Override
        public View getDropDownView(int position, View convertView,
                ViewGroup parent) {
            returngetCustomView(position, convertView, parent);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            returngetCustomView(position, convertView, parent);
        }

        public View getCustomView(int position, View convertView,
                ViewGroup parent) {

            LayoutInflater inflater = getLayoutInflater();
            View row = inflater.inflate(R.layout.row, parent, false);
            TextView label = (TextView) row.findViewById(R.id.country);
            label.setText(country[position]);

            TextView sub = (TextView) row.findViewById(R.id.currency);
            sub.setText(currency[position]);

            ImageView icon = (ImageView) row.findViewById(R.id.image);
            icon.setImageResource(arr_images[position]);

            return row;
        }
    }

}
5.Create a class JSONParser.java copy the follwwing code
packagein.ac.srmuniv.currencyconvertorjson;

importjava.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
importjava.io.InputStreamReader;
importjava.io.UnsupportedEncodingException;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
//import org.apache.http.client.methods.HttpPost;
importorg.apache.http.impl.client.DefaultHttpClient;
importorg.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

    static InputStream is = null;
    JSONObject jObj = null;

    // constructor
    public JSONParser() {

    }

    public voidgetJSONFromUrl(String url) {
        String json = "";
        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            // HttpPost httpPost = new HttpPost(url);// For google currency convertornow depricated
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();

        } catch(UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch(ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");

            }
            json = sb.toString();
            Log.d("JSON result", json);
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {

            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

    }

    double getResult() {
        double theResult = 0.0;
        try {

             //theResult = jObj.getDouble("v");
              theResult = jObj.getDouble("rate");
            System.out.println(theResult);
        }

        catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return theResult;
    }


}
4.Modify Androidmanifest.xml
<?xml version="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.ac.srmuniv.currencyconvertorjson"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="17" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/MyTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>


</manifest>
6.Copy the code  to the file string.xml in res/values folder 
<?xml version="1.0"encoding="utf-8"?>
<resources>

    <string name="app_name">SRM_CurrencyConvertorJSON</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>

    <drawable name="white">#ffffff</drawable>
    <drawable name="black">#000000</drawable>
    <drawable name="green">#347C2C</drawable>
    <drawable name="pink">#FF00FF</drawable>
    <drawable name="violet">#a020f0</drawable>
    <drawable name="grey">#778899</drawable>
    <drawable name="red">#C11B17</drawable>
    <drawable name="yellow">#FFFF8C</drawable>
    <drawable name="PowderBlue">#b0e0e6</drawable>
    <drawable name="brown">#2F1700</drawable>
    <drawable name="Hotpink">#7D2252</drawable>

    <string name="select_Category">Select Category</string>

    <drawable name="darkgrey">#606060</drawable>

    <string name="to">to</string>
    <string name="convert">Convert</string>

    <color name="bk">#F0E0D0</color>


</resources>

7.Copy the code  to the file dimens.xml in res/values folder
<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="convert">20sp</dimen>
    <dimen name="out">70sp</dimen>
    <dimen name="headsize">22sp</dimen>


</resources>

8.Copy the code  to the file styles.xml in res/layout folder 
<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.

    -->
    <style name="AppBaseTheme"parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.


        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme"parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

    <style name="CustomTheme"parent="android:Theme">
        <item name="android:windowTitleSize">40dip</item>
        <item name="android:windowTitleBackgroundStyle">@style/AppTheme</item>
    </style>

    <style name="MyTheme"parent="android:Theme.Light">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@color/bk</item>
        <item name="android:listViewStyle">@style/MySpinnerView</item>
    </style>

    <style name="MySpinnerView"parent="@android:style/Widget.Spinner">
        <item name="android:spinnersShown">@drawable/euro</item>
    </style>

    <style name="CodeFont"parent="@android:style/TextAppearance.Medium">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">fill_parent</item>
        <item name="android:textColor">#00BFA0</item>
        <item name="android:typeface">monospace</item>
    </style>


</resources>  
9.Run the device/emulator with internet connection available



Fig 1 Shows the JSON based currency convertor app taking currency rate from www.rate-exchange.appspot.com a google appengine based service
CODE EXPLANATION
The currency convertor app has  Mainactivity which contains appropriate UI.User can select currencies through spinners and value entered through editText.The values are appended to URL of json based webservice.MainActivity uses AsyncTask for making webservice request and fetching result.


Figure 2 Shows the rate -exchange google appengine based json webservice 
                                                     JSONParser class uses HttpClient class with HttpGet method to send values of from_currency ,to_currency and the amount of value to be converted.
 try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            // HttpPost httpPost = new HttpPost(url);// For google currency
            // convertor now depricated
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
The response received from  http://www.rate-exchange.appspot.com is stored in  String and passed as argument to the constructor of JSONObject.The following is the received json object for the get request 
{"to": "INR", "rate": 61.491999999999997, "from": "USD", "v": 614.91999999999996}
 // try parse the string to a JSON object
        try {

            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser""Error parsing data " + e.toString());


        }

.....
.....
JSONObject jObj contains various attributes but we are concerned with the attribute "v" which contains the converted rate  multiplied with value .The method getDouble returns the double value for the specified key "v".


 try {
            theResult = jObj.getDouble("v");
            System.out.println(theResult);
        }

        catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }