28
Nov
10

Invoking a REST method from an Android App


This page describes the process of creating an Android App that obtains and displays a list of countries from a server using a REST method.

Background

If my previous blog I mentioned the process of creating an application that displays a list of countries. Unfortunately the list was hard-coded into the Activity class.

For this page we will refer to a URL that returns JSON data all of countries that we want to display.

Requirements

The JSON Data

The data used for this app is located at the following URL:

https://ext-jsf.googlecode.com/svn/trunk/wordpress/2010/11/countryJSON.do

Project Modifications

Instead of building an application from the  begining we will take the existing app presented here and modify it to get data from the URL above.

Steps We will take

  1. Update AnroidManifest to allow our application to access the device’s internet connection
  2. Add a new method to CountryDataManager to get data using the built in Apache HTTP Client
  3. Modify the Activity Class to call the newly created method
  4. Modify the Adapter to use the default icon in case we don’t have a flag icon for the country

Manifest

Add the highlighted line to the AndroidManifest.xml

	<!-- Add this to request internet access for your application -->
	<uses-permission android:name="android.permission.INTERNET" />

DataManager

Add the following method to the datamanager. The code below uses build in Apache HTTP Client library.

src/com/test/CountryDataManager.java

    public List getCountriesFromServer(){
    	final DefaultHttpClient httpclient = new DefaultHttpClient();
    	final String URL =
            "http://ext-jsf.googlecode.com/svn/trunk/wordpress/2010/11/countryJSON.do";

    	ResponseHandler handler = new ResponseHandler()
    	{
    	    public String handleResponse(
    	            HttpResponse response) throws ClientProtocolException, IOException {
    	        HttpEntity entity = response.getEntity();
    	        if (entity != null) {
    	            return EntityUtils.toString(entity);
    	        } else {
    	            return null;
    	        }
    	    }
    	};

    	List countryList = new ArrayList();
    	try {
            HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 25000);
    		String response = httpclient.execute(new HttpGet(URL), handler);
    		try {
    			JSONArray jsonArray = new JSONArray(response);
    			int length = jsonArray.length();
    			for(int i=0; i < length; i++) {
    				JSONObject a = (JSONObject)jsonArray.get(i);
    				CountryItem country = parseJSONObject(a);
    				countryList.add(country);
    			}
    		} catch (JSONException e) {
    			throw new RuntimeException(e);
    		}
		} catch (ClientProtocolException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
        return countryList;
    }

Activity

Modify line 37 of CountryFlagActivity.java to call the newly created method above.

src/com/test/CountryFlagActivity.java

package com.test;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class CountryFlagActivity extends ListActivity {

    private CountryAdapter countryAdapter;
    private static final CountryDataManager countryDataManager
    = new CountryDataManager();

    private ProgressDialog m_ProgressDialog = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        this.countryAdapter = new CountryAdapter(this, R.layout.row,
                new ArrayList());
        setListAdapter(this.countryAdapter);

        Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				final List countryList = countryDataManager.getCountriesFromServer();
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
				        for(CountryItem country : countryList) {
				            countryAdapter.notifyDataSetChanged();
				            countryAdapter.add(country);
				        }
				        m_ProgressDialog.dismiss();
				        countryAdapter.notifyDataSetChanged();
					}
				});
			}
		});

        t.start();

        // shows a please wait while the data loads.
        m_ProgressDialog = ProgressDialog.show(CountryFlagActivity.this,
                "Please wait...", "Retrieving data ...", true);

        getListView().setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView parent, View view,
                    int position, long id) {
                Toast.makeText(getApplicationContext(),
                    ((TextView)((LinearLayout) view).getChildAt(1)).getText(),
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Adapter

We don’t have enough flag icon images. The list of countries coming from the server is larger then the original list we had in the previous blog. Therfore if the resource can not be found we will replace it with the default icon.

You can simply replace the getView method with the one seen below.

src/com/test/CountryAdapter.java

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.row, null);
        }
        CountryItem o = items.get(position);
        if (o != null) {
            TextView tt = (TextView) v.findViewById(R.id.toptext);
            if (tt != null) {
                tt.setText(o.getName());
            }
            ImageView im = (ImageView) v.findViewById(R.id.icon);
            if (im != null) {
            	Resources resources = getContext().getResources();
            	int identifier = resources.getIdentifier(
                        "@drawable/" + o.getIsoCode(), "drawable",
                        getContext().getPackageName());
            	if(identifier == 0) {
            		// flag not found. use the default icon.
            		identifier = resources.getIdentifier(
                            "@drawable/icon", "drawable",
                            getContext().getPackageName());
            	}
                im.setImageDrawable(resources.getDrawable(identifier));
            }
        }
        return v;
    }

Run the application

When you run the application you should see a larger list of countries. Also some of the countries will be using the default android icon.

That’s all for now. Feel free to leave comments if you run into trouble.

Advertisements

2 Responses to “Invoking a REST method from an Android App”


  1. 1 rlfe2
    May 10, 2012 at 1:16 pm

    Looks very interesting, but unfortunately it’s not possible to reproduce it as both (!) articles listed as ‘requirement’ are offline!


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 77 other followers

November 2010
S M T W T F S
« Oct   Dec »
 123456
78910111213
14151617181920
21222324252627
282930  

Blog Stats

  • 846,580 hits

%d bloggers like this: