Json data parsing is one of the most common uses for your android application. In frequent cases, you will be given an api or url with information encoded in json format and parse the information from your application. For example, almost all news feed application have to parse json data from server and display the news in the application. In this tutorial, we will learn how to make an api with json data and then parse the information from a url where information is encoded in json format. Create json data: Create a database named wcdb using PHPMyadmin. Create a table named fixture with 3 column : o matchId: Type int. o teamA: Type varchar o teamB: Type varchar. Insert data in this table using PHPMyadmin. I have inserted the world cup fixture data in this table. The first column matchId contains the serial number of the match that will be held, while teamA and teamB contain the name of the participant teams of the match. The table will look like this: Now we will write 3 php file to create json formatted data from the table. Create a folder named tech in your wamp or xamp root script folder (for me, the directory is : C:\wamp\www) and create 3 files here: Config.php DbConnect.php getFixture.php Config.php: In this file, we will set the database username, password, host name and database name. As you are using localhost for now, set the default value username, password and host name. Then set the database name which you have created. PHP: <?php // Database configurationdefine('DB_USERNAME', 'root'); define('DB_PASSWORD', '');define('DB_HOST', 'localhost');define('DB_NAME', 'wcdb');?> DbConnect.php: This file is required for establishing and closing connection with your database. PHP: <?phpclass DbConnect { private $conn; function __construct() { // connecting to database $this->connect(); } function __destruct() { $this->close(); } function connect() { include_once dirname(__FILE__) . './Config.php'; $this->conn = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD) or die(mysql_error()); // get host name, username and password from Config.php file mysql_select_db(DB_NAME) or die(mysql_error()); // get database name from Config.php return $this->conn; // return connection resource } // Close function function close() { // close db connection mysql_close($this->conn); }}?> getFixture.php: This file fetches the information from your database. First, it creates connection with database. Then it collects the information from the table (here, the table name is fixture). Then it saves the information in an array and prints the array in json format. PHP: <?phpinclude_once './DbConnect.php';function getFixture(){ $db = new DbConnect(); // array for json response of full fixture $response = array(); $response["fixture"] = array(); $result = mysql_query("SELECT * FROM fixture"); // Select all rows from fixture table while($row = mysql_fetch_array($result)){ $tmp = array(); // temporary array to create single match information $tmp["matchId"] = $row["matchId"]; $tmp["teamA"] = $row["teamA"]; $tmp["teamB"] = $row["teamB"]; array_push($response["fixture"], $tmp); } header('Content-Type: application/json'); echo json_encode($response);}getFixture();?> Now open the page http://localhost/tech/getFixture.php from your browser. The response will be this way: Code: {"fixture":[{"matchId":"1","teamA":"BRAZIL","teamB":"CROATIA"},{"matchId":"2","teamA":"MEXICO","teamB":"CAMEROON"},{"matchId":"3","teamA":"SPAIN","teamB":"NETHERLANDS"},{"matchId":"4","teamA":"CHILE","teamB":"AUSTRALIA"},{"matchId":"5","teamA":"COLOMBIA","teamB":"GREECE"},{"matchId":"6","teamA":"URUGUAY","teamB":"COSTA RICA"},{"matchId":"7","teamA":"ENGLAND","teamB":"ITALY"},{"matchId":"8","teamA":"IVORY COAST","teamB":"JAPAN"},{"matchId":"9","teamA":"SWITZERLAND","teamB":"ECUADOR"},{"matchId":"10","teamA":"FRANCE","teamB":"HONDURAS"},{"matchId":"11","teamA":"ARGENTINA","teamB":"BOSNIA"},{"matchId":"12","teamA":"GERMANY","teamB":"PORTUGAL"},{"matchId":"13","teamA":"IRAN","teamB":"NIGERIA"},{"matchId":"14","teamA":"GHANA","teamB":"USA"},{"matchId":"15","teamA":"BELGIUM","teamB":"ALGERIA"},{"matchId":"16","teamA":"BRAZIL","teamB":"MEXICO"},{"matchId":"17","teamA":"RUSSIA","teamB":"SOUTH KOREA"},{"matchId":"18","teamA":"AUSTRALIA","teamB":"NETHERLANDS"},{"matchId":"19","teamA":"SPAIN","teamB":"CHILE"},{"matchId":"20","teamA":"CAMEROON","teamB":"CROATIA"},{"matchId":"21","teamA":"COLOMBIA","teamB":"IVORY COAST"},{"matchId":"22","teamA":"URUGUAY","teamB":"ENGLAND"},{"matchId":"23","teamA":"JAPAN","teamB":"GREECE"},{"matchId":"24","teamA":"ITALY","teamB":"COSTA RICA"},{"matchId":"25","teamA":"SWITZERLAND","teamB":"FRANCE"},{"matchId":"26","teamA":"HONDURAS","teamB":"ECUADOR"},{"matchId":"27","teamA":"ARGENTINA","teamB":"IRAN"},{"matchId":"28","teamA":"GERMANY","teamB":"GHANA"},{"matchId":"29","teamA":"NIGERIA","teamB":"BOSNIA"},{"matchId":"30","teamA":"BELGIUM","teamB":"RUSSIA"},{"matchId":"31","teamA":"SOUTH KOREA","teamB":"ALGERIA"},{"matchId":"32","teamA":"USA","teamB":"PORTUGAL"}]} For your convenience, I am formatting the response here: Code: {"fixture":[ { "matchId":"1", "teamA":"BRAZIL", "teamB":"CROATIA" }, { "matchId":"2", "teamA":"MEXICO", "teamB":"CAMEROON" }, { "matchId":"3", "teamA":"SPAIN", "teamB":"NETHERLANDS" }, { "matchId":"4", "teamA":"CHILE", "teamB":"AUSTRALIA" }, {"matchId":"5", "teamA":"COLOMBIA", "teamB":"GREECE" }, { "matchId":"6", "teamA":"URUGUAY", "teamB":"COSTA RICA" }, { "matchId":"7", "teamA":"ENGLAND", "teamB":"ITALY" }, { "matchId":"8", "teamA":"IVORY COAST", "teamB":"JAPAN" }, { "matchId":"9", "teamA":"SWITZERLAND", "teamB":"ECUADOR"}, { "matchId":"10", "teamA":"FRANCE", "teamB":"HONDURAS" }, { "matchId":"11", "teamA":"ARGENTINA", "teamB":"BOSNIA" }, { "matchId":"12", "teamA":"GERMANY", "teamB":"PORTUGAL" }, { "matchId":"13", "teamA":"IRAN", "teamB":"NIGERIA" }, { "matchId":"14", "teamA":"GHANA", "teamB":"USA"}, { "matchId":"15", "teamA":"BELGIUM", "teamB":"ALGERIA" }, { "matchId":"16", "teamA":"BRAZIL", "teamB":"MEXICO" }, { "matchId":"17", "teamA":"RUSSIA", "teamB":"SOUTH KOREA" }, { "matchId":"18", "teamA":"AUSTRALIA", "teamB":"NETHERLANDS" }, { "matchId":"19", "teamA":"SPAIN", "teamB":"CHILE" }, { "matchId":"20", "teamA":"CAMEROON", "teamB":"CROATIA" }, { "matchId":"21", "teamA":"COLOMBIA", "teamB":"IVORY COAST" }, {"matchId":"22", "teamA":"URUGUAY", "teamB":"ENGLAND" }, { "matchId":"23", "teamA":"JAPAN", "teamB":"GREECE" }, { "matchId":"24", "teamA":"ITALY", "teamB":"COSTA RICA" }, { "matchId":"25", "teamA":"SWITZERLAND", "teamB":"FRANCE" }, { "matchId":"26", "teamA":"HONDURAS", "teamB":"ECUADOR" }, { "matchId":"27", "teamA":"ARGENTINA", "teamB":"IRAN" }, { "matchId":"28", "teamA":"GERMANY", "teamB":"GHANA" }, { "matchId":"29", "teamA":"NIGERIA", "teamB":"BOSNIA" }, { "matchId":"30", "teamA":"BELGIUM", "teamB":"RUSSIA" }, { "matchId":"31", "teamA":"SOUTH KOREA", "teamB":"ALGERIA" }, { "matchId":"32", "teamA":"USA", "teamB":"PORTUGAL" } ] } Parse json data: Now, we will create our android application and parse the json data from the server in this application. Open eclipse and start a new android application. Your default activity name will be MainActivity.java and default layout file will be activity_main.xml Create a new class named Servicehandler.java and save it in src folder. Create a new xml file named list_item.xml and save it in res->layout folder. activity_main.xml: It is the main layout file of your application. We have used a table layout to display the information in tabular format. In first row, three (3) textview elements are used as table header. The header texts are: Match, Team and Team. In the Match column, match id will be shown, and in the two Team columns, name of the two participant teams will be displayed. To display this information, a listview is used in the second row, which will be used to display the list of match id and participant team names. Here is the source code of activity_main.xml Code: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TableLayout android:layout_width="match_parent" android:layout_height="match_parent" android:shrinkColumns="*" android:stretchColumns="*" android:background="#000000"> <TableRow android:id="@+id/tableRow1" android:layout_height="wrap_content" android:layout_width="match_parent"> <TextView android:id="@+id/matchId" android:text="Match" android:layout_weight="1" android:textColor="#00ff00" android:gravity="center"/> <TextView android:id="@+id/teamA" android:text="Team" android:layout_weight="1" android:textColor="#00ff00" android:gravity="center"/> <TextView android:id="@+id/vs" android:layout_weight="1" android:textColor="#00ff00" android:gravity="center"/> <TextView android:id="@+id/teamB" android:text="Team" android:layout_weight="1" android:textColor="#00ff00" android:gravity="center"/> </TableRow> <ListView android:id="@android:id/list" android:divider="@android:color/darker_gray" android:dividerHeight="3dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView> </TableLayout> </RelativeLayout> list_item.xml: This is a layout file which will be loaded in the main layout to display the match information. Here, a table layout is used to display information in tabular format. There are four columns in this layout with id: matchId, teamA, vs, teamB. The matched, teamA and teamb information will be loaded from json response; the vs field is used to show a text “vs” between two teams. For example, the output format will be: Code: 1 Brazil vs Croatia Where, 1 is matched, Brazil is teamA and Croatia is teamB. Here is the source code of list_item.xml Code: <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:shrinkColumns="*" android:stretchColumns="*" android:background="#000000"> <TableRow android:id="@+id/tableRow1" android:layout_height="wrap_content" android:layout_width="match_parent"> <TextView android:id="@+id/matchId" android:layout_weight="1" android:width="60dp" android:textColor="#ffffff" android:gravity="center"/> <TextView android:id="@+id/teamA" android:layout_weight="2" android:width="60dp" android:textColor="#ffffff" android:gravity="center"/> <TextView android:id="@+id/vs" android:text="vs" android:layout_weight="1" android:width="20dp" android:textColor="#ffffff" android:gravity="center"/> <TextView android:id="@+id/teamB" android:layout_weight="2" android:width="60dp" android:textColor="#ffffff" android:gravity="center"/> </TableRow> </TableLayout> AndroidManifest.xml: It is the configuration file of your application. Here is one important change you need to make: Add the following line: Code: <uses-permission android:name="android.permission.INTERNET"/> As we need to access the internet in this application, we need to mention it in the manifest file. So our manifest file will be something like it: Code: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.testjsonparsing" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> ServiceHandler.java: This file is used for http request and response handling. There is a function makeServiceCall with two different signatures (function overloading). You can use any of them according to your requirement. String makeServiceCall(String url, int method) String makeServiceCall(String url, int method,List<NameValuePair> params) Let’s look at the parameters: String url: Provide the url you want to hit in the server. int method: Provide the method you want to use, either GET or POST. List<NameValuePair> params: Provide list of parameters you want to send to get your filtered response or to store new data information. Here is the full code of ServiceHandler.java file. Code: package com.example.testjsonparsing; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.impl.client.DefaultHttpClient; import android.util.Log; public class ServiceHandler { static InputStream is = null; static String response = null; public final static int GET = 1; public final static int POST = 2; public ServiceHandler() { } public String makeServiceCall(String url, int method) { return this.makeServiceCall(url, method, null); } public String makeServiceCall(String url, int method, List<NameValuePair> params) { try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity httpEntity = null; HttpResponse httpResponse = null; if (method == POST) { HttpPost httpPost = new HttpPost(url); if (params != null) { httpPost.setEntity(new UrlEncodedFormEntity(params)); } httpResponse = httpClient.execute(httpPost); } else if (method == GET) { if (params != null) { String paramString = URLEncodedUtils .format(params, "utf-8"); url += "?" + paramString; } HttpGet httpGet = new HttpGet(url); httpResponse = httpClient.execute(httpGet); } 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, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); response = sb.toString(); } catch (Exception e) { Log.e("Buffer Error", "Error: " + e.toString()); } return response; } } MainActivity.java: This file is used to send information to service handler class to retrieve information from the server and then display it in application layout. To perform this, we have to consider the following things: Don’t implement http request and response call in the main thread. It will block your main thread, so UI will be blocked and unwanted situation may occur. We will use Asynctask method to perform communication with server. Let’s look at the steps we need to follow: Our MainActivity class will extend ListActivity because we will display information in a list. Code: public class MainActivity extends ListActivity { } Provide the url from which you want to get json response. Code: private String URL_ITEMS = "http://10.0.2.2/tech/getFixture.php"; Set the tag name by which you will parse the information from json response. If you look at the response, you can see the main array name is fixture and in every element in the fixture, there are three individual information of matchId, teamA and teamB. So, we will use these tag to parse the data. Code: private static final String TAG_FIXTURE = "fixture"; private static final String TAG_MATCHID = "matchId"; private static final String TAG_TEAMA = "teamA"; private static final String TAG_TEAMB = "teamB"; Use a JSONArray to store the information and an arraylist which will be used later to display information in ListView. Code: JSONArray matchFixture = null; ArrayList<HashMap<String, String>> matchFixtureList = new ArrayList<HashMap<String, String>>(); Create a class which will extend asynctask. We will perform communication with server and display information using this class. Code: private class GetFixture extends AsyncTask<Void, Void, Void> { } Override 3 methods in this class: 1. protected void onPreExecute() : This function performs any required task before data fetch for data send. We are doing nothing in this function. You can show any progress bar, loading messages or other things here. 2. protected Void doInBackground(Void... arg) : The main background tasks are performed here. The steps we would follow are: Using ServiceHandler class, call the makeServicecall function with url and method. ServiceHandler serviceClient = new ServiceHandler(); String json = serviceClient.makeServiceCall(URL_ITEMS,ServiceHandler.GET); Response is received in a string(json). In the JSON Array matchfixture, store the array fixture of the json response. matchFixture = jsonObj.getJSONArray(TAG_FIXTURE); Get the length of the matchfixture array. Then parse the matched, teamA and teamB data for every child node. Create a hashmap for every single node as key – value coding and add each child node to hashmap key. At last, add all child node to matchfixture arraylist. Code: matchFixture = jsonObj.getJSONArray(TAG_FIXTURE); Log.d("json aray", "user point array"); int len = matchFixture.length(); Log.d("len", "get array length"); for (int i = 0; i < matchFixture.length(); i++) { JSONObject c = matchFixture.getJSONObject(i); String matchId = c.getString(TAG_MATCHID); Log.d("matchId", matchId); String teamA = c.getString(TAG_TEAMA); Log.d("teamA", teamA); String teamB = c.getString(TAG_TEAMB); Log.d("teamB", teamB); // hashmap for single match HashMap<String, String> matchFixture = new HashMap<String, String>(); // adding each child node to HashMap key => value matchFixture.put(TAG_MATCHID, matchId); matchFixture.put(TAG_TEAMA, teamA); matchFixture.put(TAG_TEAMB, teamB); matchFixtureList.add(matchFixture); } 3. protected void onPostExecute(Void result): This function performs any required action after background communication. In our application, we will display the json response in a listview, and this task will be performed in post execute method. Create a SimpleAdapter and use it as a ListAdapter. Code: protected void onPostExecute(Void result) { super.onPostExecute(result); ListAdapter adapter = new SimpleAdapter( MainActivity.this, matchFixtureList, R.layout.list_item, new String[] { TAG_MATCHID, TAG_TEAMA,TAG_TEAMB } , new int[] { R.id.matchId,R.id.teamA, R.id.teamB } ); setListAdapter(adapter); } Let’s see the signature of the SimpleAdapter we have used here. Code: android.widget.SimpleAdapter.SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) * The parameters are: Context context : Provide context of the application. Just use the activity name in which you want to use the adapter. So, it is MainActivity.this for our example. List<? extends Map<String, ?>> data: Provide data to display. In this application, we have stored the response in an ArrayList named matchFixtureList. int resource : Provide the resource name where you want to display the data. Here, we want to display the information in our layout file named list_item. String[] from : Provide array of String which you want to display. Here, the information is saved in matchId, teamA and teamB, which we have saved in TAG_MATCHID, TAG_TEAMA and TAG_TEAMB. int[] to : Provide array of resource identifier where we want to display the information. In list_item.xml file, there are three textview with id: matched, teamA and teamB. These can be referenced from the java file using resource identifier: R.id.matchId,R.id.teamA and R.id.teamB individually. Finally, call the GetFixture method which extends AsyncTask from onCreate method of your application, because we want to fetch information and display the information as soon as the application starts. Code: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Call Async task to get the match fixture new GetFixture().execute(); } If you want to send any parameter to GetFixture()method, send it from here. For example: Code: new GetFixture().execute(parameter(s)); Here is the source code of MainActivity.java file. Code: package com.example.testjsonparsing; import java.util.ArrayList; import java.util.HashMap; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.os.AsyncTask; import android.os.Bundle; import android.app.ListActivity; import android.util.Log; import android.view.Menu; import android.widget.ListAdapter; import android.widget.SimpleAdapter; public class MainActivity extends ListActivity { private String URL_ITEMS = "http://10.0.2.2/tech/getFixture.php"; private static final String TAG_FIXTURE = "fixture"; private static final String TAG_MATCHID = "matchId"; private static final String TAG_TEAMA = "teamA"; private static final String TAG_TEAMB = "teamB"; JSONArray matchFixture = null; ArrayList<HashMap<String, String>> matchFixtureList = new ArrayList<HashMap<String, String>>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Call Async task to get the match fixture new GetFixture().execute(); } private class GetFixture extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(Void... arg) { ServiceHandler serviceClient = new ServiceHandler(); Log.d("url: ", "> " + URL_ITEMS); String json = serviceClient.makeServiceCall(URL_ITEMS,ServiceHandler.GET); // print the json response in the log Log.d("Get match fixture response: ", "> " + json); if (json != null) { try { Log.d("try", "in the try"); JSONObject jsonObj = new JSONObject(json); Log.d("jsonObject", "new json Object"); // Getting JSON Array node matchFixture = jsonObj.getJSONArray(TAG_FIXTURE); Log.d("json aray", "user point array"); int len = matchFixture.length(); Log.d("len", "get array length"); for (int i = 0; i < matchFixture.length(); i++) { JSONObject c = matchFixture.getJSONObject(i); String matchId = c.getString(TAG_MATCHID); Log.d("matchId", matchId); String teamA = c.getString(TAG_TEAMA); Log.d("teamA", teamA); String teamB = c.getString(TAG_TEAMB); Log.d("teamB", teamB); // hashmap for single match HashMap<String, String> matchFixture = new HashMap<String, String>(); // adding each child node to HashMap key => value matchFixture.put(TAG_MATCHID, matchId); matchFixture.put(TAG_TEAMA, teamA); matchFixture.put(TAG_TEAMB, teamB); matchFixtureList.add(matchFixture); } } catch (JSONException e) { Log.d("catch", "in the catch"); e.printStackTrace(); } } else { Log.e("JSON Data", "Didn't receive any data from server!"); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); ListAdapter adapter = new SimpleAdapter( MainActivity.this, matchFixtureList, R.layout.list_item, new String[] { TAG_MATCHID, TAG_TEAMA,TAG_TEAMB } , new int[] { R.id.matchId,R.id.teamA, R.id.teamB } ); setListAdapter(adapter); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } Screenshot of the output: Here are some screenshots of the output of the application. Figure 1 : Screenshot of the application(1) Figure 2: Screenshot of the application (2)
i tried the code to display stock market prices. problem is that when the app is launched, it only displays the elements(i.e green) but doesnt return any data from the URL, so the rest of the table is blank.
Hi shabbir........ as mentioned by some of people above is the same think happens wid me....it only showing elements of the layout...............in the code... main activity.java wen we are calling makeservicecall function its passing only two parameters ......in serviceHandler the defination of the funtion makeservicecall requires three parameters.........i think error is over der...................and wen i run the application its showing me the Json object is having a null value............
Suresh, there is one more function that accepts the third parameter if you want to be using that and so it is not issue as far as I can see. Code: public String makeServiceCall(String url, int method, List<NameValuePair> params)
shabbir...........my list view is nt loading the contetn from server ...in console its hsowing my json object is null..........
Debug why object is NULL because if the object is null, Does your server sends the data over JSON? Is it configured to be doing that? Can you share the JSON data url
yes sure........... i have posted in fb my link bcoz i cant able to send here ..........................according to my data i have modified my inner code......................
In FB you have posted your local link http://127.0.0.1/freshBakery/getOrderedData.php Which is not something I can access and see anything.
Shabbir Sir ......... ListView is not loading the content from the server. Please provide solution to this problem as soon as possible. Thanks in advance.