How to display information in a ListView after parsing the JSON response from a Web server
In this example our goal is to make a Web Request, basically a HTTP POST, as soon as the activity starts on another thread using AsyncTask and then wait for the response. The response is a JSON formatted MySQL data from a Java Servlet that provides us with a array of countries with some additional information. We then parse the JSON data and with the help custom ArrayAdapter display on our List.Source for Activity - AndroidListViewJSONActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | package com.as400samplecode; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.google.gson.Gson; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; public class AndroidListViewJSONActivity extends Activity { ArrayList<Country> countryList; MyCustomAdapter dataAdapter = null ; int start = 0 ; int limit = 9999 ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); grabURL(url); } public void grabURL(String url) { Log.v( "Android Spinner JSON Data Activity" , url); new GrabURL().execute(url); } private class GrabURL extends AsyncTask<String, Void, String> { private static final int REGISTRATION_TIMEOUT = 3 * 1000 ; private static final int WAIT_TIMEOUT = 30 * 1000 ; private final HttpClient httpclient = new DefaultHttpClient(); final HttpParams params = httpclient.getParams(); HttpResponse response; private String content = null ; private boolean error = false ; private ProgressDialog dialog = new ProgressDialog(AndroidListViewJSONActivity. this ); protected void onPreExecute() { dialog.setMessage( "Getting your data... Please wait..." ); dialog.show(); } protected String doInBackground(String... urls) { String URL = null ; try { URL = urls[ 0 ]; HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT); ConnManagerParams.setTimeout(params, WAIT_TIMEOUT); HttpPost httpPost = new HttpPost(URL); //add name value pair for the country code List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>( 2 ); nameValuePairs.add( new BasicNameValuePair( "start" ,String.valueOf(start))); nameValuePairs.add( new BasicNameValuePair( "limit" ,String.valueOf(limit))); httpPost.setEntity( new UrlEncodedFormEntity(nameValuePairs)); response = httpclient.execute(httpPost); StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() == HttpStatus.SC_OK){ ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); out.close(); content = out.toString(); } else { //Closes the connection. Log.w( "HTTP1:" ,statusLine.getReasonPhrase()); response.getEntity().getContent().close(); throw new IOException(statusLine.getReasonPhrase()); } } catch (ClientProtocolException e) { Log.w( "HTTP2:" ,e ); content = e.getMessage(); error = true ; cancel( true ); } catch (IOException e) { Log.w( "HTTP3:" ,e ); content = e.getMessage(); error = true ; cancel( true ); } catch (Exception e) { Log.w( "HTTP4:" ,e ); content = e.getMessage(); error = true ; cancel( true ); } return content; } protected void onCancelled() { dialog.dismiss(); Toast toast = Toast.makeText(AndroidListViewJSONActivity. this , "Error connecting to Server" , Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 25 , 400 ); toast.show(); } protected void onPostExecute(String content) { dialog.dismiss(); Toast toast; if (error) { toast = Toast.makeText(AndroidListViewJSONActivity. this , content, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 25 , 400 ); toast.show(); } else { displayCountryList(content); } } } private void displayCountryList(String response){ JSONObject responseObj = null ; try { Gson gson = new Gson(); responseObj = new JSONObject(response); JSONArray countryListObj = responseObj.getJSONArray( "countryList" ); countryList = new ArrayList<Country>(); for ( int i= 0 ; i<countryListObj.length(); i++){ //get the country information JSON object String countryInfo = countryListObj.getJSONObject(i).toString(); //create java object from the JSON object Country country = gson.fromJson(countryInfo, Country. class ); //add to country array list countryList.add(country); } //create an ArrayAdaptar from the String Array dataAdapter = new MyCustomAdapter( this , R.layout.country_info, countryList); ListView listView = (ListView) findViewById(R.id.listView1); // Assign adapter to ListView listView.setAdapter(dataAdapter); //enables filtering for the contents of the given ListView listView.setTextFilterEnabled( true ); listView.setOnItemClickListener( new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // When clicked, show a toast with the TextView text Country country = (Country) parent.getItemAtPosition(position); Toast.makeText(getApplicationContext(), country.getCode(), Toast.LENGTH_SHORT).show(); } }); } catch (JSONException e) { e.printStackTrace(); } } private class MyCustomAdapter extends ArrayAdapter<Country> { private ArrayList<Country> countryList; public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<Country> countryList) { super (context, textViewResourceId, countryList); this .countryList = new ArrayList<Country>(); this .countryList.addAll(countryList); } private class ViewHolder { TextView code; TextView name; TextView continent; TextView region; } @Override public View getView( int position, View convertView, ViewGroup parent) { ViewHolder holder = null ; Log.v( "ConvertView" , String.valueOf(position)); if (convertView == null ) { LayoutInflater vi = (LayoutInflater)getSystemService( Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.country_info, null ); holder = new ViewHolder(); holder.code = (TextView) convertView.findViewById(R.id.code); holder.name = (TextView) convertView.findViewById(R.id.name); holder.continent = (TextView) convertView.findViewById(R.id.continent); holder.region = (TextView) convertView.findViewById(R.id.region); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Country country = countryList.get(position); holder.code.setText(country.getCode()); holder.name.setText(country.getName()); holder.continent.setText(country.getContinent()); holder.region.setText(country.getRegion()); return convertView; } } } |
Source for POJO - Country.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | package com.as400samplecode; public class Country { String code = null ; String name = null ; String continent = null ; String region = null ; Double lifeExpectancy = null ; Double gnp = null ; Double surfaceArea = null ; int population = 0 ; public String getCode() { return code; } public void setCode(String code) { this .code = code; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getContinent() { return continent; } public void setContinent(String continent) { this .continent = continent; } public String getRegion() { return region; } public void setRegion(String region) { this .region = region; } public Double getLifeExpectancy() { return lifeExpectancy; } public void setLifeExpectancy(Double lifeExpectancy) { this .lifeExpectancy = lifeExpectancy; } public Double getGnp() { return gnp; } public void setGnp(Double gnp) { this .gnp = gnp; } public Double getSurfaceArea() { return surfaceArea; } public void setSurfaceArea(Double surfaceArea) { this .surfaceArea = surfaceArea; } public int getPopulation() { return population; } public void setPopulation( int population) { this .population = population; } } |
Source for Main Screen Layout - main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 | <? xml version = "1.0" encoding = "utf-8" ?> 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:padding = "10dp" android:text = "@string/some_text" android:textSize = "20sp" /> < ListView android:id = "@+id/listView1" android:layout_width = "fill_parent" android:layout_height = "fill_parent" /> </ LinearLayout > |
Source for List Layout - country_info.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | <? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:orientation = "vertical" android:padding = "6dip" > < TextView android:id = "@+id/textView1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignParentLeft = "true" android:layout_alignParentTop = "true" android:text = "Code: " android:textAppearance = "?android:attr/textAppearanceMedium" /> < TextView android:id = "@+id/textView2" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignLeft = "@+id/textView1" android:layout_below = "@+id/textView1" android:text = "Name: " android:textAppearance = "?android:attr/textAppearanceMedium" /> < TextView android:id = "@+id/textView3" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignLeft = "@+id/textView2" android:layout_below = "@+id/textView2" android:text = "Continent: " android:textAppearance = "?android:attr/textAppearanceMedium" /> < TextView android:id = "@+id/textView4" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignLeft = "@+id/textView3" android:layout_below = "@+id/textView3" android:text = "Region: " android:textAppearance = "?android:attr/textAppearanceMedium" /> < TextView android:id = "@+id/continent" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignBaseline = "@+id/textView3" android:layout_alignBottom = "@+id/textView3" android:layout_toRightOf = "@+id/textView3" android:text = "TextView" /> < TextView android:id = "@+id/region" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignBaseline = "@+id/textView4" android:layout_alignBottom = "@+id/textView4" android:layout_alignLeft = "@+id/continent" android:text = "TextView" /> < TextView android:id = "@+id/name" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_above = "@+id/textView3" android:layout_toRightOf = "@+id/textView3" android:text = "TextView" /> < TextView android:id = "@+id/code" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_above = "@+id/textView2" android:layout_alignLeft = "@+id/name" android:text = "TextView" /> </ RelativeLayout > |
Source for application variables - strings.xml
1 2 3 4 5 6 7 8 9 | <? xml version = "1.0" encoding = "utf-8" ?> < resources > < string name = "app_name" >ListView JSON Web Data</ string > < string name = "some_text" > Some North American Countries! </ string > </ resources > |
Source for application manifest - AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <? xml version = "1.0" encoding = "utf-8" ?> package = "com.as400samplecode" android:versionCode = "1" android:versionName = "1.0" > < uses-sdk android:minSdkVersion = "15" /> < uses-permission android:name = "android.permission.INTERNET" /> < uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" /> < uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" /> < uses-permission android:name = "android.permission.ACCESS_COARSE_LOCATION" /> < application android:icon = "@drawable/ic_launcher" android:label = "@string/app_name" android:theme = "@android:style/Theme.Light" > < activity android:name = ".AndroidListViewJSONActivity" 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 > |
Source for Java Servlet - CountryServlet.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | package com.as400samplecode; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.as400samplecode.util.Country; import com.as400samplecode.util.CountryInformation; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; public class CountryServlet extends HttpServlet { private static final long serialVersionUID = 1L; public CountryServlet() { super (); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String start = request.getParameter( "start" ); String limit = request.getParameter( "limit" ); PrintWriter out = response.getWriter(); response.setContentType( "text/html" ); response.setHeader( "Cache-control" , "no-cache, no-store" ); response.setHeader( "Pragma" , "no-cache" ); response.setHeader( "Expires" , "-1" ); response.setHeader( "Access-Control-Allow-Origin" , "*" ); response.setHeader( "Access-Control-Allow-Methods" , "GET,POST" ); response.setHeader( "Access-Control-Allow-Headers" , "Content-Type" ); response.setHeader( "Access-Control-Max-Age" , "86400" ); //get list of countries CountryInformation countryInformation = new CountryInformation(); ArrayList<Country> countryList = countryInformation.getList(start, limit); Gson gson = new Gson(); JsonArray arrayObj= new JsonArray(); for ( int i= 0 ;i<countryList.size();i++){ Country country = countryList.get(i); JsonElement countryObj = gson.toJsonTree(country); arrayObj.add(countryObj); } //create a new JSON object JsonObject myObj = new JsonObject(); //add property as success myObj.addProperty( "success" , true ); //add the countryList object myObj.add( "countryList" , arrayObj); //convert the JSON to string and send back out.println(myObj.toString()); out.close(); } } |
Source for database utility functions - CountryInformation.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | package com.as400samplecode.util; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; import java.util.ArrayList; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; public class CountryInformation { Connection conn = null ; PreparedStatement stmt = null ; String sql = null ; public ArrayList<Country> getList(String start, String limit) { ArrayList<Country> countryList = new ArrayList<Country>(); try { Context ctx = (Context) new InitialContext().lookup( "java:comp/env" ); conn = ((DataSource) ctx.lookup( "jdbc/mysql" )).getConnection(); sql = "Select * from COUNTRY order by name,code LIMIT ?,?" ; stmt = conn.prepareStatement(sql); stmt.setInt( 1 ,Integer.parseInt(start)); stmt.setInt( 2 ,Integer.parseInt(limit)); ResultSet rs = stmt.executeQuery(); while (rs.next()){ Country country = new Country(); country.setCode(rs.getString( "code" ).trim()); country.setName(rs.getString( "name" ).trim()); country.setContinent(rs.getString( "continent" ).trim()); country.setRegion(rs.getString( "region" ).trim()); country.setLifeExpectancy(rs.getString( "lifeExpectancy" ) == null ? new Double( 0 ) : Double.parseDouble(rs.getString( "lifeExpectancy" ) .trim())); country.setGnp(rs.getString( "gnp" ) == null ? new Double( 0 ) : Double.parseDouble(rs.getString( "gnp" ).trim())); country.setSurfaceArea(rs.getString( "surfaceArea" ) == null ? new Double( 0 ) : Double.parseDouble(rs.getString( "surfaceArea" ).trim())); country.setPopulation(rs.getString( "population" ) == null ? 0 : Integer.parseInt(rs.getString( "population" ).trim())); countryList.add(country); } rs.close(); stmt.close(); stmt = null ; conn.close(); conn = null ; } catch (Exception e){System.out.println(e);} finally { /* * close any jdbc instances here that weren't * explicitly closed during normal code path, so * that we don't 'leak' resources... */ if (stmt != null ) { try { stmt.close(); } catch (SQLException sqlex) { // ignore -- as we can't do anything about it here } stmt = null ; } if (conn != null ) { try { conn.close(); } catch (SQLException sqlex) { // ignore -- as we can't do anything about it here } conn = null ; } } return countryList; } } |
No comments:
Post a Comment
NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.