Posts Tagged ‘android

02
Dec
10

Opening a New Activity in Android

This page describes the process of creating an Android application that will present the user with a Navigation Menu. When the user clicks they will be directed to either the “Product” or “Location” page. The “breakout” pages will have a back button that allows the user to return to the main menu.

Background

This page Covers:

  • Page Layouts
  • Creating ListView with menu items and icons
  • Creating Buttons and defining onClickListeners
  • Creating and starting Activities using Intents

Requirements

Create a new Project

  1. In eclipse Right click New -> project, choose “Android Project”
  2. Project Name: AndroidNav
  3. Package name: com.test
  4. Create Activity: MainMenuActivity
  5. Click Finish

Define the Resources

Define the resource strings

res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Custom Navigation Main Menu</string>
    <string name="product">Product</string>
    <string name="locations">Locations</string>
</resources>

Layout Files

Main Menu Activity presents a ListView containing 2 choices. Each item in the list has an icon to the left and to the right of the text. When the user clicks on the item a new page displays.

/res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	
	<ListView android:id="@+id/ListView01" 
		android:layout_width="fill_parent" 
		android:layout_height="wrap_content">		
	</ListView>

</LinearLayout>

Each row of the ListView seen above is defined by the following xml file. Each row contains an icon to the left and right of the text. An additional LinearLayout was required to get the icon to align/justify to the right.

/res/layout/row.xml

<?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="horizontal">
    
    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:src="@drawable/icon"/>

	<TextView
	    android:id="@+id/toptext"
	    android:padding="5dp"
	    android:textSize="10pt"
	    android:layout_width="wrap_content"
	    android:layout_height="fill_parent" />
	
	<LinearLayout 
	    android:layout_width="fill_parent" android:layout_height="fill_parent"	    
	    android:orientation="horizontal"
	    android:gravity="right|center_vertical">
		<ImageView		
			android:id="@+id/navIcon"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"			
			android:src="@android:drawable/ic_media_play"			
			/>
	</LinearLayout>
	    			    
</LinearLayout>

The Product and the Location page are the “breakout” pages. They have a back button on the bottom.

/res/layout/product.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	
	<TextView android:text="Product Menu" android:textSize="15pt"
		android:layout_width="fill_parent" android:layout_height="wrap_content"
		android:layout_weight="1" />

	<Button android:id="@+id/productReturnToMainButton" 
	android:layout_height="wrap_content"
		android:text="&lt; Back to Main Menu" 
		android:layout_centerInParent="true"
		android:layout_width="fill_parent"></Button>

</LinearLayout>

/res/layout/locations.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	
	<TextView android:text="Locations" android:textSize="15pt"
		android:layout_width="fill_parent" android:layout_height="wrap_content"
		android:layout_weight="1" />

	<Button android:id="@+id/locationReturnToMainButton" 
	android:layout_height="wrap_content"
		android:text="&lt; Back to Main Menu" 
		android:layout_centerInParent="true"
		android:layout_width="fill_parent"></Button>

</LinearLayout>

Activity Classes

The following is the main activity class. This class listens to events from the ListView. It contains a switch statement that directs the user to the appropriate page based on their selection. I know its not really the best way to do it, if you guys have a suggestion to improve it please post a comment.

src/com/test/MainMenuActivity.java

package com.test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class MainMenuActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setTitle("Custom Navigation Main Menu");
        
        //get the reference to the list view defined in main.xml layout.
        final ListView listView = (ListView)findViewById(R.id.ListView01);
        
		listView.setAdapter(new ArrayAdapter<String>(this, R.layout.row,
				R.id.toptext, new String[] {
						getResources().getString(R.string.product),
						getResources().getString(R.string.locations) }));
        
        listView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
            	switch(position) {
            	case 0: 
    				Toast.makeText(getApplicationContext(),
    						"Product List Item was clicked.",
    				        Toast.LENGTH_SHORT).show();
					startActivity(new Intent(getApplicationContext(),
							ProductMenuActivity.class));
    			    break;
            	case 1:
    				Toast.makeText(getApplicationContext(),
							"Locations List Item was clicked.",
					        Toast.LENGTH_SHORT).show();								
					startActivity(new Intent(getApplicationContext(),
							LocationMenuActivity.class));
    				break;
            	}
            }
        });
    }
}

The following two activities are very similar. The implementation of the Back functionality in both are done by calling finish(). This might not be the best way of doing it since the main menu could have already been killed by android to re-claim memory.

src/com/test/LocationMenuActivity.java

package com.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class LocationMenuActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.locations);
        Button returnToMainButton = (Button)findViewById(R.id.locationReturnToMainButton);
        if(returnToMainButton!=null) {
        	returnToMainButton.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
				    finish();
				}
			});        
        }
    }
}

src/com/test/ProductMenuActivity.java

package com.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ProductMenuActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.product);
        
        Button returnToMainButton = (Button)findViewById(R.id.productReturnToMainButton);
        if(returnToMainButton!=null) {
        	returnToMainButton.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
				    finish();
				}
			});        
        }
    }
}

Android Manifest

The manifest file contains definitions for:

  1. Application Name (Label)
  2. Icon that represents the application
  3. Each Activity
  4. The “Main” Activity that will run when the application starts

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainMenuActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".ProductMenuActivity"
                  android:label="@string/app_name">
        </activity>
        <activity android:name=".LocationMenuActivity"
                  android:label="@string/app_name">
        </activity>
    </application>
</manifest> 

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.

17
Nov
10

Android Development Hello World

This page describes the procedure to create and run a “Hello World” application. Although the application is simple, it does however give you an opportunity to test the proper functionality of your development environment.

Background

We will create a new project in eclipse and define 2 files. The first one is the Activity Class. You can consider this class to be filling the role as a Servlet class. The other class is the View (similar to a JSP).

Requirements

Create a New Android Project

  1. In eclipse Right click New -> project, choose “Android Project”
  2. Project Name: AndroidHelloApp
  3. Package name: com.test
  4. Create Activity: HelloActivity
  5. Click Finish

The following file will automatically be created for you. For all of you that come from a JEE background, this file is similar to the Servlet Class.

src/com/test/HelloActivity.java

package com.test;

import android.app.Activity;
import android.os.Bundle;

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

The onCreate() callback method gets invoked when the App starts up. The highlighted item above indicates that main.xml should be loaded.

Create the Layout File (View)

For all of you that come from a JEE background, this file is similar to the JSP page.

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">

	<TextView android:text="Hello World!" android:textSize="15pt"
		android:layout_width="fill_parent" android:layout_height="wrap_content"
		android:layout_weight="1" />

</LinearLayout>

Run The application

Note: If you get an error in the project saying that the gen source folder is missing then open the “HelloActivity.java” file and add an extra line at the end, then save.

Right click on the project and click “Run As” -> “Android Application’.

17
Nov
10

Setting up for Android 2.2 Development

This page describes the process of setting up an Android 2.2 development environment for your Linux or windows desktop. At the end this page you will have the right tools to develop your first Hello World Android Application. The instructions are based on Ubuntu however I will try to cover where the instructions differ for windows.

Background

Google developed an SDK and an Eclipse plug-in that allows developers to create, test and deploy applications to the Android smart phones. In order to ensure that there will be no lack of app developers and quest to dominate the Mobile Platform Google has made these tools and infrastructure available free! Any average Joe with some programming background can create a cool Android Apps in their spare time, publish it to the Android Market place and make some extra cash.

Requirements

  • Java 5 or above
  • Eclipse 3.4 or above Installed and configured

Download the SDK from Google

http://developer.android.com/sdk/index.html

Its okay to download the Linux (i386) 32 bit version even if you have a 64 bit Linux. Just make sure you have the proper 32 bit binary compatibility packages installed in your Linux installation. (Just click on the System Requirements link and read carefully)

Once the SDK is installed, write down where it was installed ( For the examples on this page I will assume it was installed into “/home/verma/usr/local/android-sdk-linux_x86″.

Eclipse Update Manager

Install the Android Plugin via update Manager

URL: https://dl-ssl.google.com/android/eclipse/

Once installed go to Windows->Preferences and click on Android.

Fill in the location where you installed your SDK and save.

Next Select Window -> Android SDK and AVD Manager.

Click on the Available Packages Item on the left of the popup window.

Select :

  • Documentation for Android SDK, API 8, revision 1
  • SDK Platform Android 2.2, API 8, revision 1
  • Samples for SDK API 8, revision 1

Click Install Selected and confirm the licence for all.

Restart Eclipse.

Define a Virtual Device

Select Window -> Android SDK and AVD Manager. This time click Virtual Devices then click the “New” button.

  • Name your Device (Be creative, but not too creative – avoid funny characters or spaces)
  • Target: Android 2.2 – API Level 8
  • Leave the rest as default
  • Click Create AVD.

The AVD should show up on the list. Select it and click start. You should get another window to popup with an android screen on the left and a few button and a keyboard on the right. This is your test device. It is just like the actual phone however it is easier to work with since it is on your computer.

Eventually We will cover how to telnet into the device to simulate events like.

  • change network status
  • change GPS location
  • Battery Charge status changes
  • simulate inbound phone call
  • etc…

Next Steps

Create a Hello World Application

 




Follow

Get every new post delivered to your Inbox.

Join 34 other followers