I will use JSON data from the following RESTful API
http://www.cmcredit.com/apps/apis/map/
It is a country/region/city database I put together from various sources and you query by sending some NVP parameters. I will also explain how to do this in our android application. Just as a quick example calling the API with the NVP
{call: countrylist}
will do the get request: http://www.cmcredit.com/apps/apis/map/?call=countrylist
and return a country listing. To get regions in a country you could call the api with the NVPs {call: countryregions, country_id: 42}
. This API is used for demo purposes ONLY.
We will use data returned from http://www.cmcredit.com/apps/apis/map/?call=countrylist which is of the following format:
{ "success":true, "message":"", "data": [ {"country_id":"42","name":"cameroon","iso2":"CM","currency":"XAF"}, {"country_id":"43","name":"canada","iso2":"CA","currency":"CAD"}, {"country_id":"44","name":"cape verde","iso2":"CV","currency":"CVE"}, {"country_id":"45","name":"cayman islands","iso2":"KY","currency":"KYD"}, {"country_id":"46","name":"central african republic","iso2":"CF","currency":"XAF"}, {"country_id":"47","name":"chad","iso2":"TD","currency":"XAF"} ] }
Create the various Layouts
1. Activity layout: one TextView and one Spinner (res/layout/activity_spinnerdemo.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingTop="30dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:paddingLeft="10dp" android:text="@string/list_country" > </TextView> <Spinner android:id="@+id/countryField" android:layout_width="match_parent" android:layout_height="wrap_content" android:prompt="@string/select_country" > </Spinner> </LinearLayout>
The TextView will simply display the text of the android:text attribute on the screen and the spinner will be populated by our Activity class.
2. The layout of each item in the spinner (res/layout/simple_spinner_item.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/item_value" android:layout_width="wrap_content" android:layout_height="wrap_content" > </TextView> <TextView android:id="@+id/item_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFF" > </TextView> </LinearLayout>
Define the Activity class
Secondly we define our activity class that will be launched when you start your application (if you set it as the main activity in the AndroidManifest.xml)
SpinnerDemo.java
package com.sewoyebah.examples; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Spinner; import android.widget.Toast; import android.annotation.SuppressLint; import android.app.Activity; @SuppressLint("DefaultLocale") public class SpinnerDemo extends Activity { // JSON Node names private static final String TAG_DATA = "data"; private static final String TAG_ID_COUNTRY = "country_id"; private static final String TAG_NAME = "name"; private static final String TAG_ISO = "iso2"; private static final String TAG_CURRENCY = "currency"; private static final String MAP_API_URL = "http://www.cmcredit.com/apps/apis/map"; private BackGroundTask bgt; // Fields Spinner countryField; ArrayList<Country> countryList = new ArrayList<Country>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_spinnerdemo); buildCountryDropDown(); } public void buildCountryDropDown() { // Building post parameters, key and value pair List<NameValuePair> apiParams = new ArrayList<NameValuePair>(1); apiParams.add(new BasicNameValuePair("call", "countrylist")); bgt = new BackGroundTask(MAP_API_URL, "GET", apiParams); try { JSONObject countryJSON = bgt.execute().get(); // Getting Array of countries JSONArray countries = countryJSON.getJSONArray(TAG_DATA); // looping through All countries for (int i = 0; i < countries.length(); i++) { JSONObject c = countries.getJSONObject(i); // Storing each json item in variable String id = c.getString(TAG_ID_COUNTRY); String name = c.getString(TAG_NAME); String iso = c.getString(TAG_ISO); String currency = c.getString(TAG_CURRENCY); // add Country countryList.add(new Country(id, name.toUpperCase(), iso, currency)); } // bind adapter to spinner countryField = (Spinner) findViewById(R.id.countryField); CountryAdapter cAdapter = new CountryAdapter(this, android.R.layout.simple_spinner_item, countryList); countryField.setAdapter(cAdapter); countryField.setOnItemSelectedListener(new OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { Country selectedCountry = countryList.get(position); showToast(selectedCountry.getName() + " was selected!"); } @Override public void onNothingSelected(AdapterView<?> parent) {} }); } catch (JSONException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } public void showToast(String msg) { Toast.makeText(this, "Toast: " + msg, Toast.LENGTH_LONG).show(); } }
Code Explanation
First we define some strings that represent the keys of our JSON data (TAG_DATA to TAG_CURRENCY), then we define our API end point MAP_API_URL.
In Android development ,it is recommended not to make http requests on the same thread that displays the user interface (i.e requests are best made asynchronous and not as a blocking operation). This is why I defined a background class called BackGroundTask.java (Code is at the end of this article), that handles all such request. Android provides a class called AsyncTask which enables asynchronous requests so my BackgroundTask class will just be extending this class and overriding some core functions. You can read more about this from the Android documentation.
Define the Spinner countryField as in the layout and finally we define the ArrayList
The onCreate is called when your activity is started and in it we set the content view and call our
buildCountryDropdown()
method.
What happens in the
buildCountryDropDown()
method?
1. Set the parameters to be sent to the API by defining a NameValuePair list.
ListapiParams = new ArrayList (1); apiParams.add(new BasicNameValuePair("call", "countrylist"));
2. Start the background task
bgt = new BackGroundTask(MAP_API_URL, "GET", apiParams);
Initiating our background class, we pass as parameters the API end point, the method to use for the request and the NVP parameters. 3. Get response from the background task
JSONObject countryJSON = bgt.execute().get();
The try..catch block that follows is pretty straight forward. From the JSON object shown above, you will notice that the necessary data itself is in a JSON array, which is why to get the data, we use
JSONArray countries = countryJSON.getJSONArray(TAG_DATA);
Each item in the countries JSONArray is a JSONObject so to get the entries of each item in the countries Array, we use
JSONObject c = countries.getJSONObject(i);
where i is the current position of the iteration. And finally to get the value of each entry you use the
getString()
method of the JSONObject
class. For example to get the id of a country, you use
String id = c.getString(TAG_ID_COUNTRY);
At the end of the for loop after getting the values of the entries in a country, you add the country to the countryList ArrayList
countryList.add(new Country(id, name, iso, currency));
(The code defining the country class is given at the end of this topic.)
The last and final thing that needs to be done to complete our demo is to bind the country list to the spinner. This is done using an ArrayAdapter and because we have a custom type
Country
we define our own custom adapter called CountryAdapter
, that extends the ArrayAdapter
class. If the list we wanted to bind to the spinner was a list of String
s, we need not define a custom adapter. we counld directly use the ArrayAdapter.
//get country spinner view from the layout countryField = (Spinner) findViewById(R.id.countryField); //define adapter to be used when displaying the country list CountryAdapter cAdapter = new CountryAdapter(this, android.R.layout.simple_spinner_item, countryList); //bind the adapter to the spinner countryField.setAdapter(cAdapter); //set a listener for selected items in the spinner countryField.setOnItemSelectedListener(new OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { Country selectedCountry = countryList.get(position); showToast(selectedCountry.getName() + " was selected!"); } });
And that will be it. For detailed explanations on Android Classes used in this tutorial, you can visit the Android Developers site.
Other Classes Necessary for this tutorial:
Country.java
package com.sewoyebah.examples; public class Country { private String id; private String name; private String iso2; private String currency; public Country(String i, String n, String iso, String curr) { id = i; name = n; iso2 = iso; currency = curr; } public String getId() { return id; } public String getName() { return name; } public String getISO2() { return iso2; } public String getCurency() { return currency; } public String toString() { return name; } }
CountryAdapter.java
package com.sewoyebah.examples; import java.util.ArrayList; import android.app.Activity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; public class CountryAdapter extends ArrayAdapter<Country> { private Activity context; ArrayList<Country> data = null; public CountryAdapter(Activity context, int resource, ArrayList<Country> data) { super(context, resource, data); this.context = context; this.data = data; } @Override public View getView(int position, View convertView, ViewGroup parent) { return super.getView(position, convertView, parent); } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { View row = convertView; if (row == null) { LayoutInflater inflater = context.getLayoutInflater(); row = inflater.inflate(R.layout.simple_spinner_item, parent, false); } Country item = data.get(position); if (item != null) { // Parse the data from each object and set it. TextView CountryId = (TextView) row.findViewById(R.id.item_id); TextView CountryName = (TextView) row.findViewById(R.id.item_value); if (CountryId != null) { CountryId.setText(item.getId()); } if (CountryName != null) { CountryName.setText(item.getName()); } } return row; } }
BackGroundTask.java
package com.sewoyebah.examples; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; 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 org.json.JSONException; import org.json.JSONObject; import android.os.AsyncTask; import android.util.Log; public class BackGroundTask extends AsyncTask<String, String, JSONObject> { List<NameValuePair> postparams = new ArrayList<NameValuePair>(); String URL = null; String method = null; static InputStream is = null; static JSONObject jObj = null; static String json = ""; public BackGroundTask(String url, String method, List<NameValuePair> params) { this.URL = url; this.postparams = params; this.method = method; } @Override protected JSONObject doInBackground(String... params) { // TODO Auto-generated method stub // Making HTTP request try { // Making HTTP request // check for request method if (method.equals("POST")) { // request method is POST DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(URL); httpPost.setEntity(new UrlEncodedFormEntity(postparams)); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } else if (method == "GET") { // request method is GET DefaultHttpClient httpClient = new DefaultHttpClient(); String paramString = URLEncodedUtils .format(postparams, "utf-8"); URL += "?" + paramString; HttpGet httpGet = new HttpGet(URL); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } // read input stream returned by request into a string using StringBuilder 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(); json = sb.toString(); // create a JSONObject from the json string jObj = new JSONObject(json); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } // return JSONObject (this is a class variable and null is returned if something went bad) return jObj; } }
Ignore the closing tags at the end of the code snippets, the script formatting the code snippets just messes up.
In the County Adapter class what is the variable R.layout.dropdown_value_id a reference to? A spinner id?
RépondreSupprimerEdit never mind i see its a reference to a layout.... however i dont see that layout in this tutorial?
nice work by the way
Ce commentaire a été supprimé par l'auteur.
RépondreSupprimerEste ce que on peut faire le download du code?
RépondreSupprimerC'est plus facile, pou pouvoi voir le code et le tester avec un format de Json que je suis en train d'utilizer.
Je vous remercie.
apakah saya blh minta project nya yg sudah berbentuk project eclipse ?
RépondreSupprimerBeaver says I also have such interest, you can read my profile here: currency exchange online
RépondreSupprimerHVAC & Plumbing Services
RépondreSupprimerAir Star Heating guarantees reliability and quality for all equipment and services.
Air Star Heating specialists always try to deliver the most excellent quality of services to our customers at an affordable price. It is understood that every client has different needs and different problems. We try to accomplish the needs of every client according to their requests. We are having considerable experience in this field. Our specialists understand very well how things work. It doesn’t matter in which field of industry you are looking for services.
Plumbing & HVAC Services in San Diego. Call now (858) 900-9977 ✓Licensed & Insured ✓Certified Experts ✓Same Day Appointment ✓Original Parts Only ✓Warranty On Every Job.
Visit:- https://airstarheating.com