Documentation Android

110
ANDROID DOCUMENTATION COMPILED BY FASTOP http://fastoponandroid.googlepages.com/ http://fastoponandroid.googlepages.com/ http://fastoponandroid.googlepag

Transcript of Documentation Android

Page 1: Documentation Android

ANDROID DOCUMENTATIONCOMPILED BY FASTOP

http://fastoponandroid.googlepages.com/ http://fastoponandroid.googlepages.com/ http://fastoponandroid.googlepages.com/

Page 2: Documentation Android

Android - An Open Handset Alliance Project

The Android platform is a software stack for mobile devices including an operating system, middleware and key applications.

Developers can create applications for the platform using the Android SDK. Applications are written using the Java

programming language and run on Dalvik, a custom virtual machine designed for embedded use which runs on top of a

Linux kernel.

If you want to know how to develop applications for Android , you're in the right place. This site provides a variety of

documentation that will help you learn about Android and develop mobile applications for the platform.

An early look at the the Android SDK is also available. It includes sample projects with source code, development tools, an

emulator, and of course all the libraries you'll need to bui ld an Android application.

Download the SDK

To start learning about the Android platform, please read the documentation in the following order:

What is Android?

An overview of the Android platform

Getting Started

All the basics, including Hello World

Developing Applications

The nuts and bolts of Android applications

Developer Toolbox

In-depth information on specific topics

Reference Information

A myriad of reference material

Sample Code

Several sample Android applications for your viewing pleasure

Frequently Asked Questions

Common issues and questions

Welcome to Android!

1Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 3: Documentation Android

Android is a software stack for mobile devices that includes an operating system, middleware and key

applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing

applications on the Android platform using the Java programming language.

Application framework enabling reuse and replacement of components

Dalvik virtual machine optimized for mobile devices

Integrated browser based on the open source WebKit engine

Optimized graphics powered by a custom 2D graphics library; 3D graphics based on the OpenGL ES 1.0

specification (hardware acceleration optional)

SQLite for structured data storage

Media support for common audio, video, and still image formats (MPEG4, H.264, MP3, AAC, AMR, JPG,

PNG, GIF)

GSM Telephony (hardware dependent)

Bluetooth, EDGE, 3G, and WiFi (hardware dependent)

Camera, GPS, compass, and accelerometer (hardware dependent)

Rich development environment including a device emulator, tools for debugging, memory and

performance profiling, and a plugin for the Eclipse IDE

The following diagram shows the major components of the Android operating system. Each section is described

in more detail below.

What is Android?

Features

Android Architecture

2Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 4: Documentation Android

Android will ship with a set of core applications including an email client, SMS program, calendar, maps, browser,

contacts, and others. All applications are written using the Java programming language.

Developers have full access to the same framework APIs used by the core applications. The application

architecture is designed to simplify the reuse of components; any application can publish its capabilities and any

other application may then make use of those capabilities (subject to security constraints enforced by the

framework). This same mechanism allows components to be replaced by the user.

Underlying all applications is a set of services and systems, includ ing:

A rich and extensible set of Views that can be used to build an application, including li sts, grids, text boxes,

buttons, and even an embeddable web browser

Content Providers that enable applications to access data from other applications (such as Contacts), or to

share their own data

A Resource Manager, providing access to non-code resources such as localized strings, graph ics, and

layout files

A Notification Manager that enables all applications to display custom alerts in the status bar

An Activity Manager that manages the lifecycle of applications and provides a common navigation

backstack

Applications

Application Framework

For more details and a walkthrough of an application, see Writing an Android Application .

Android includes a set of C/C++ libraries used by various components of the Android system. These capabilities

are exposed to developers through the Android application frame work. Some of the core libraries are listed

below:

System C library - a BSD-derived implementation of the standard C system library (libc), tuned for

embedded Linux-based devices

Media Libraries - based on PacketVideo's OpenCORE; the libraries support playback and recording of

many popular audio and video formats, as well as static image f iles, including MPEG4, H.264, MP3, AAC,

AMR, JPG, and PNG

Surface Manager - manages access to the display subsystem and seamlessly composites 2D and 3D

graphic layers from multiple applications

LibWebCore - a modern web browser engine which powers both the Android b rowser and an embeddable

web view

SGL - the underlying 2D graphics engine

3D libraries - an implementation based on OpenGL ES 1.0 APIs; the libraries use either hardware 3D

acceleration (where available) or the included, highly optimize d 3D software rasterizer

FreeType - bitmap and vector font rendering

SQLite - a powerful and lightweight relational database engin e available to all applications

Libraries

3Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 5: Documentation Android

Android includes a set of core libraries that provides most of the functionality available in the core libraries of the

Java programming language.

Every Android application runs in its own process, with its own instance of the Dalvik virtual machine. Dalvik has

been written so that a device can run multiple VMs efficiently. The Dalvik VM executes files in the Dalvik

Executable (.dex) format which is optimized for minimal memory footprint. The VM is register-based, and runs

classes compiled by a Java language compiler that have been transf ormed into the .dex format by the included

"dx" tool.

The Dalvik VM relies on the Linux kernel for underlying functionality such as threading and low-level memory

management.

Android relies on Linux version 2.6 for core system services such as security, memory management, process

management, network stack, and driver model. The kernel also acts as an abstraction layer between the

hardware and the rest of the software stack.

Android Runtime

Linux Kernel

To get started with Android, please read the following sections first:

Installing the SDK and Plugin

How to install the SDK and Eclipse plugin, or how to use other tools to build Android applications. Also a guide to

running the sample applications.

Hello Android!

Writing your first Android Application, the ever popular Hello World, Android style.

Anatomy of an Android Application

A guide to the structure and architecture of an Android Applicat ion. This guide will help you understand the pieces that

make up an Android app.

Tutorial: Building a Full Android Application

This tutorial document will lead you through constructing a real Android Application: A notepad which can create, edit

and delete notes, and covers many of the basic concepts with practical examples.

Development Tools

The command line tools included with the SDK, what they do, and how to use them.

Lifecycle of an Android Application

The important lifecycle details for Applications and Activities running inside of them.

Getting Started with Android

After reading the sections above, the following Getting Started information is also very useful:

These are the basic packages that make up the Android SDK for writ ing applications. The packages are organized as

layers, listed here from lowest-level to highest.

android.util

contains various low-level utility classes, such as specialized contai ner classes, XML utilities, etc.

android.os

provides basic operating system services, message passing, and inter-process communication.

Other Introductory Material

Core Packages

4Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 6: Documentation Android

android.graphics

is the core rendering package.

android.text, android.text.method, android.text.style, and android.text.util

supply a rich set of text processing tools, supporting rich text, input methods, etc.

android.database

contains low-level APIs for working with databases.

android.content

provides various services for accessing data on the device: applications installed on the device and their associated

resources, and content providers for persistent dynamic data.

android.view

is the core user-interface framework.

android.widget

supplies standard user interface elements (lists, buttons, layout managers, etc) built from the view package.

android.app

provides the high-level application model, implemented using Activities.

These packages provide additional domain-specific features of the Android platform. They are not necessary for basic

application development.

android.provider

contains definitions for various standard content providers included with the platform.

android.telephony

provides APIs for interacting with the device's phone stack.

android.webkit

includes various APIs for working with web-based content.

Other Notable Packages

5Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 7: Documentation Android

First impressions matter, and as a developer you know that the first impression you get of a development

framework is how easy it is to write "Hello, World!" Well, in Android, it's pretty easy. Here's how it looks:

Create the Project

Construct the UI

Run the Code: Hello, Android

The sections below spell it all out in detail.

Upgrading the UI to an XML Layout

Debugging Your Project

Creating a Project without Eclipse

Let's jump in!

Creating the project is as simple as can be. An Eclipse plugin is available making Android development a

snap. You'll need to have Eclipse 3.2 or 3.3 installed, and you'll need to install the Android Plugin for

Eclipse. Once you have those installed, come back here.

First, here's a high-level summary of how to build "Hello, World!":

Create a new "Android Project" via the File > New > Project menu.1.

Fill out the project details in the New Android Project dialog.2.

Edit the auto-generated source code template to display some output.3.

That's it! Next, let's go through each step above in detail.

Create a new Android Project

From Eclipse, select the File > New > Project menu item. If the Android Plugin for Eclipse has been

successfully installed, the resulting dialog should have a folder labeled "Android" which should contain

a single entry: "Android Project".

1.

Hello, Android!

Create the Project

Once you've selected "Android Project", press the Next button.

6Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 8: Documentation Android

Fill out the project details

The next screen allows you to enter the relevant details for your project. Here's an example:

2.

Here's what each field on this screen means:

Project

Name

This is the name of the directory or folder on your computer that you want to

contain the project.

Package

Name

This is the package namespace — similar to the Java programming language —

that you want all your source code to reside under. This also sets the package

name under which the stub Activity will be generated.

The package name you use in your application must be unique across all

packages installed on the system; for this reason, it's very important to use a

standard domain-style package for your applications. In the example above, we

used the package domain "com.google.android"; you should use a different one

appropriate to your organization.

Activity

Name

This is the name for the class stub that will be generated by the plugin. This will

be a subclass of Android's Activity class. An Activity is simply a class that can run

and do work. It can create a UI if it chooses, but it doesn't need to.

Application

Name

This is the human-readable title for your application.

The checkbox for toggling "Use default location" allows you to change the location on disk where the

project's files will be generated and stored.

7Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 9: Documentation Android

Edit the auto-generated source code

After the plugin runs, you'll have a class named HelloAndroid that looks like this:

public class HelloAndroid extends Activity

{

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle)

{

super.onCreate(icicle);

setContentView(R.layout.main);

}

}

The next step is to start modifying it!

3.

Once you've got the project set up, the obvious next step is to get some text up there on the screen. Here's

the finished product — next we'll dissect it line by line:

public class HelloAndroid extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

TextView tv = new TextView(this);

tv.setText("Hello, Android");

setContentView(tv);

}

}

Note that you should also add import android.widget.TextView; to the import statements in order

for this example to compile.

In Android, user interfaces are composed of hierarchies of classes called Views. A View is simply a

drawable object, such as a radio button, an animation, or (in our case) a text label. The specific name for

the View subclass that handles text is simply TextView.

Here's how you construct a TextView:

TextView tv = new TextView(this);

The argument to TextView's constructor is an Android Context instance. The Context is simply a handle to

the system; it provides services like resolving resources, obtaining access to databases and preferences,

and so on. The Activity class inherits from Context. Since our HelloAndroid class is a subclass of Activity, it

is also a Context, and so we can pass the 'this' reference to the TextView.

Construct the UI

8Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 10: Documentation Android

Nothing too surprising there.

At this point, we've constructed a TextView and told it what text to display. The final step is to connect this

TextView with the on-screen display, like so:

setContentView(tv);

The setContentView() method on Activity indicates to the system which View should be associated with the

Activity's UI. If an Activity doesn't call this method, no UI is present at all and the system will display a blank

screen. For our purposes, all we want is to display some text, so we pass it the TextView we just created.

There it is — "Hello, World" in Android! The next step, of course, is to see it running.

The Eclipse plugin makes it very easy to run your applications. Begin by selecting the Run > Open Run

Dialog menu entry; you should see a dialog like this:

Run the Code: Hello, Android

Once we've constructed the TextView, we need to tell it what to display:

tv.setText("Hello, Android");

Next, highlight the "Android Application" entry, and then press the icon in the top left corner (the one

depicting a sheet of paper with a plus sign in the corner) or simply double-click the "Android Application"

entry. You should have a new launcher entry named "New_configura tion".

9Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 11: Documentation Android

Change the name to something expressive, like "Hello, Android", and then pick your project by pressing the

Browse button. (If you have more than one Android project open in Eclipse, be sure to pick the right one.)

The plugin will automatically scan your project for Activity subclasses, and add each one it finds to the

drop-down list under the "Activity:" label. Since your "Hello, Android" project only has one, it will be the

default, and you can simply continue.

Press the "Apply" button. Here's an example:

That's it — you're done! Press the Run button, and the Android Emulator should start. Once it's booted up

your application will appear. When all is said and done, you should see something like this:

10Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 12: Documentation Android

That's "Hello, World" in Android. Pretty straightforward, eh? The next sections of the tutorial offer more

detailed information that you may find valuable as you learn more about Android.

Upgrading the UI to an XML Layout

The "Hello, World" example you just completed uses what we call "programmatic" UI layout. This means

that you construct and build your application's UI directly in source code. If you've done much UI

programming, you're probably familiar with how brittle that approach can sometimes be: small changes in

layout can result in big source-code headaches. It's also very easy to forget to properly connect Views

together, which can result in errors in your layout and wasted time debugging your code.

That's why Android provides an alternate UI construction model: XML-based layout files. The easiest way to

explain this concept is to show an example. Here's an XML layout file that is identical in behavior to the

programmatically-constructed example you just completed:

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com /apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:text="Hello, Android"/>

The general structure of an Android XML layout file is simple. It's a tree of tags, where each tag is the name

of a View class. In this example, it's a very simple tree of one element, a TextView. You can use the name

of any class that extends View as a tag name in your XML layouts, including custom View classes you

define in your own code. This structure makes it very easy to quickly build up UIs, using a much simpler

structure and syntax than you would in source code. This model is inspired by the web development model,

where you can separate the presentation of your application (i ts UI) from the application logic used to fetch

and fill in data.

11Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 13: Documentation Android

In this example, there are also four XML attributes. Here's a summary of what they mean:

Attribute Meaning

xmlns:android This is an XML namespace declaration that tells the Android tools that

you are going to refer to common attributes defined in the Android

namespace. The outermost tag in every Android layout file must have

this attribute.

android:layout_width This attribute defines how much of the available width on the screen

this View should consume. In this case, it's our only View so we want it

to take up the entire screen, which is what a value of "fill_parent"

means.

android:layout_height This is just like android:layout_width, except that it refers to available

screen height.

android:text This sets the text that the TextView should contain. In this example, it's

our usual "Hello, Android" message.

So, that's what the XML layout looks like, but where do you put it? Under the res/ directory in your project.

The "res" is short for "resources" and that directory contains all the non-code assets that your application

requires. This includes things like images, localized strings, and XML layout files.

The Eclipse plugin creates one of these XML files for you. In our example above, we simply never used it. In

the Package Explorer, expand the folder res/layout, and edit the file main.xml. Replace its contents with the

text above and save your changes.

Now open the file named R.java in your source code folder in the Package Explorer. You'll see that it now

looks something like this:

public final class R {

public static final class attr {

};

public static final class drawable {

public static final int icon=0x7f020000;

};

public static final class layout {

public static final int main=0x7f030000;

};

public static final class string {

public static final int app_name=0x7f040000 ;

};

};

A project's R.java file is an index into all the resources defined in the file. You use this class in your source

code as a sort of short-hand way to refer to resources you've included in your project. This is particularly

powerful with the code-completion features of IDEs like Eclipse because it lets you quickly and interactively

locate the specific reference you're looking for.

The important thing to notice for now is the inner class named "layout", and its member field "main". The

Eclipse plugin noticed that you added a new XML layout file and then regenerated this R.java file. As you

add other resources to your projects you'll see R.java change to keep up.

12Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 14: Documentation Android

The last thing you need to do is modify your HelloAndroid source code to use the new XML version of your

UI, instead of the hard-coded version. Here's what your new class will look like. As you can see, the source

code becomes much simpler:

public class HelloAndroid extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

}

}

When you make this change, don't just copy-and-paste it in. Try out the code-completion feature on that R

class. You'll probably find that it helps a lot.

Now that you've made this change, go ahead and re-run your application — all you need to do is press the

green Run arrow icon, or select Run > Run Last Launched from the menu. You should see.... well, exactly

the same thing you saw before! After all, the point was to show that the two different layout approaches

produce identical results.

There's a lot more to creating these XML layouts, but that's as far as we'll go here. Read the Implementing a

User Interface documentation for more information on the power of this approach.

The Android Plugin for Eclipse also has excellent integration w ith the Eclipse debugger. To demonstrate

this, let's introduce a bug into our code. Change your HelloAndroid source code to look like this:

Debugging Your Project

public class HelloAndroid extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

Object o = null;

o.toString();

setContentView(R.layout.main);

}

}

This change simply introduces a NullPointerException into your code . If you run your application again,

you'll eventually see this:

13Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 15: Documentation Android

To find out what went wrong, set a breakpoint in your source code on the line "Object o = null;" (You can do

this by double-clicking on the region to the left of the line number in Eclipse.) Then select Run > Debug Last

Launched from the menu to enter debug mode. Your app will restart in the emulator, but this time it will

suspend when it reaches the breakpoint you set. You can then step through the code in Eclipse's Debug

Perspective, just as you would for any other application.

If you don't use Eclipse (such as if you prefer another IDE, or simply use text editors and command line

tools) then the Eclipse plugin can't help you. Don't worry though — you don't lose any functionality just

because you don't use Eclipse.

The Android Plugin for Eclipse is really just a wrapper around a set of tools included with the Android SDK.

(These tools, like the emulator, aapt, adb, ddms, and others are documented elsewhere.) Thus, it's possible

to wrap those tools with another tool, such as an 'ant' build file.

The Android SDK includes a Python script named "activityCreator.py" that can be used to create all the

source code and directory stubs for your project, as well as an ant-compatible build.xml file. This allows you

to build your project from the command line, or integrate it with the IDE of your choice.

For example, to create a HelloAndroid project similar to the one we just created via Eclipse, you'd use this

command:

activityCreator.py --out HelloAndroid com.google.an droid.hello.HelloAndroid

To build the project, you'd then run the command 'ant'. When that command successfully completes, you'll

be left with a file named HelloAndroid.apk under the 'bin' directory. That .apk file is an Android Package,

and can be installed and run in your emulator using the 'adb' tool.

For more information on how to use these tools, please read the documentation cited above.

Creating the Project without Eclipse

14Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 16: Documentation Android

There are four building blocks to an Android application:

Activity

Intent Receiver

Service

Content Provider

Not every application needs to have all four, but your application will be written with some combination of these.

Once you have decided what components you need for your applica tion, you should list them in a file called

AndroidManifest.xml. This is an XML file where you declare the components of your application and what their capabilities

and requirements are. See the Android manifest file documentation for complete details.

Activities are the most common of the four Android building blocks. An activity is usually a single screen in your application.

Each activity is implemented as a single class that extends the Activity base class. Your class will display a user interface

composed of Views and respond to events. Most applications consist of multiple screens. For example, a text messaging

application might have one screen that shows a list of contacts to send messages to, a second screen to write the message

to the chosen contact, and other screens to review old messages or change settings. Each of these screens would be

implemented as an activity. Moving to another screen is accomplished by a starting a new activity. In some cases an activity

may return a value to the previous activity -- for example an activity that lets the user pick a photo would return the chosen

photo to the caller.

When a new screen opens, the previous screen is paused and put onto a history stack. The user can navigate backward

through previously opened screens in the history. Screens can also choose to be removed from the history stack when it

would be inappropriate for them to remain. Android retains history stacks for each application launched from the home

screen.

Android uses a special class called an Intent to move from screen to screen. An intent describes what an application wants

done. The two most important parts of the intent data structure are the action and the data to act upon. Typical values for

action are MAIN (the front door of the activity), VIEW, PICK, EDIT, etc. The data is expressed as a URI. For example, to

view contact information for a person, you would create an intent with the VIEW action and the data set to a URI

representing that person.

There is a related class called an IntentFilter. While an intent is effectively a request to do something, an intent filter is a

description of what intents an activity (or intent receiver, see below) is capable of handling. An activity that is able to display

contact information for a person would publish an IntentFil ter that said that it knows how to handle the action VIEW when

applied to data representing a person. Activities publish the ir IntentFilters in the AndroidManifest.xml file.

Navigating from screen to screen is accomplished by resolving intents. To navigate forward, an activity calls

startActivity(myIntent). The system then looks at the intent filters for all installed applications and picks the activity

whose intent filters best matches myIntent. The new activity is informed of the intent, which causes it to be launched. The

process of resolving intents happens at run time when startActivity is called, which offers two key benefits:

Activities can reuse functionality from other components simply by making a request in the form of an Intent

Activities can be replaced at any time by a new Activity with an equivalent IntentFilter

Anatomy of an Android Application

Activity

Intent and Intent Filters

15Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 17: Documentation Android

You can use an IntentReceiver when you want code in your application to execute in reaction to an external event, for

example, when the phone rings, or when the data network is available, or when it's midnight. Intent receivers do not display

a UI, although they may use the NotificationManager to alert the user if something interesting has happened. Intent receivers

are registered in AndroidManifest.xml, but you can also register them from code using Context.registerReceiver().

Your application does not have to be running for its intent receivers to be called; the system will start your application, if

necessary, when an intent receiver is triggered. Applications can a lso send their own intent broadcasts to others with

Context.broadcastIntent().

A Service is code that is long-lived and runs without a UI. A good example of this is a media player playing songs from a play

list. In a media player application, there would probably be one or more activities that allow the user to choose songs and

start playing them. However, the music playback itself should not be handled by an activity because the user will expect the

music to keep playing even after navigating to a new screen. In this case, the media player activity could start a service

using Context.startService() to run in the background to keep the music going. The system will then keep the music

playback service running until it has finished. (You can learn more about the priority given to services in the system by

reading Lifecycle of an Android Application .) Note that you can connect to a service (and start it if it's not already running)

with the Context.bindService() method. When connected to a service, you can communicate with it through an

interface exposed by the service. For the music service, this might allow you to pause, rewind, etc.

Applications can store their data in files, an SQLite database, or any other mechanism that makes sense. A content provider,

however, is useful if you want your application's data to be shared with other applications. A content provider is a class that

implements a standard set of methods to let other applications store and retrieve the type of data that is handled by that

content provider.

To get more details on content providers, see Accessing Content Providers .

Service

Content Provider

Intent Receiver

16Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 18: Documentation Android

The tutorial in this section gives you a "hands-on" introduction to the Android framework and the tools you use to build

applications on it. Starting from a preconfigured project file, it guides you through the process of developing a simple

notepad application and provides concrete examples of how to set up the project, develop the application logic and user

interface, and then compile and run the application.

The tutorial presents the notepad application development as a set of exercises (see below), each consisting of several

steps. You can follow along with the steps in each exercise and gradually build up and refine your application. The exerci ses

explain each step in detail and provide all the sample code you need to complete the application.

When you are finished with the tutorial, you will have created a functioning Android application and learned in dep th about

many of the most important concepts in Android development. If you want to add more complex features to your application,

you can look at and use the code in the notepad application that is supplied in the sample code area of the Android SDK.

Who Should Use this Tutorial

Preparing for the Exercises

Exercises

Other Resources and Further Learning

This tutorial is designed for experienced developers, especially those with knowledge of the Java programming language. If

you haven't written Java applications before, you can still use the tutorial, but you might need to work at a slower pace.

Also, the tutorial builds on the information provided in the Installing the SDK and Hello Android documents, which explain in

detail how to set up your development environment for building Android applications. Before you start the tutorial, make sure

that you have already downloaded the SDK and installed it according to the instructions.

Finally, this tutorial describes how to develop the notepad application in the Eclipse development environment, with the

Android plugin installed. If you are not using Eclipse, you can follow the exercises and build the application, but you will need

to determine how to accomplish the Eclipse-specific steps in your environment. If you want to add more complex features to

your application, you can look at and use the code in the notepad application that is supplied in the sample code area of the

Android SDK.

The tutorial assumes that you have some familiarity with the basic Android application concepts and terminology. If you

aren't yet familiar with those, you should read Overview of an Android Application and Application Lifecycle before

continuing.

Before you begin, it's important that you install the SDK and set up your Eclipse development. Once your environment is set

up, locate and unpack the exercises archive, which is included in the SDK package. The archive includes a series of Eclipse

project files that are used in the exercises. You can use these project files instead of creating and configuring your own

project files.

To get the tutorial project files:

Download the project exercises archive (.zip)1.

Tutorial: A Notepad Application

Contents

Who Should Use this Tutorial

Preparing for the Exercises

Unpack the archive file to a suitable location on your machine2.

Open the NotepadCodeLab folder3.

Inside the NotepadCodeLab folder, you should see six project files: Notepadv1, Notepadv2, Notepadv3,

Notepadv1Solution, Notepadv2Solution and Notepadv3Solution. The Notepadv* projects are the starting points

for each of the exercises, while the Notepadv*Solution projects are the exercise solutions. If you are having trouble with

a particular exercise, you can compare your current work against the exercise solution to try and track down the problem.

17Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 19: Documentation Android

The table below lists the tutorial exercises and describes the development areas that each covers. Each exercise assumes

that you have completed the previous example (if any).

Exercise 1 Construct a simple notes list that lets the user add new notes but not edit

them. Demonstrates the basics of ListActivities and creating and

handling menu options. Uses a SQLite database to store the notes.

Exercise 2 Add a second activity to the application. Demonstrates constructing a new

Activity, adding it to the Android manifest, passing data between the

activities, and using more advanced screen layout. Also shows how to

invoke another activity asynchronously using startSubActivity().

Exercise 3 Add handling of life-cycle events to the application, to let it maintain

application state across the life cycle.

Extra Credit Demonstrates how to use the Eclipse debugger and how you can use it to

view lifecycle events as they are generated. This section is optional but

highly recommended.

For a lighter but broader introduction to concepts not covered in the tutorial, take a look at Common Android Tasks .

The Android SDK includes a variety of fully functioning sample applications that make excellent opportunities for

further learning. You can find the sample applications in the samples/ directory.

This tutorial draws from the full Notepad application included in the samples/ directory of the SDK. When you are

done with the tutorial, it is highly recommended that you take a closer look at the full Notepad application, as it

demonstrates a variety of interesting additions for your applicat ion, such as:

Setting up a custom striped list for the list of notes.

Creating a custom text edit view that overrides the draw() method to make it look like a lined notepad.

Implementing a full ContentProvider for notes.

Reverting and discarding edits instead of just automatically saving them.

Exercises

Other Resources and Further Learning

In this exercise, you will construct a simple notes list that lets the user add new notes but not edit them. The exercise

demonstrates:

The basics of ListActivities and creating and handling menu options.

How to access/store the notes in an SQLite database to store the notes.

How to bind data into a ListView using an ArrayAdapter (one of the simplest ways to bind to a ListView).

The basics of screen layouts, including how to lay out a list view, how you can add items to the activity menu, and how

the activity handles those menu selections.

Tutorial: Notepad Exercise 1

Open up the Notepadv1 project in Eclipse.

Notepadv1 is a project that is provided as a starting point - it takes care of some of the boilerplate work that you have

already seen if you followed the Hello Android tutorial.

Right click in the Package Explorer, select Import.../General/Existing Projects into Workspace .a.

Hit the browse button, and navigate to where you copied the three exercise folders, select Notepadv1 and hit OK.b.

You should see Notepadv1 listed in the projects with a check mark next to it.c.

Hit Finish.d.

The exercise project should be open and ready to go in your Eclipse package explorer.e.

If you see an error about AndroidManifest.xml, or some problems related to an Android zip file, right click on the

project and select Android Tools->Fix Project Properties from the popup menu (the project is looking in the wrong

location for the library file, this will fix it for you).

f.

Step 1

18Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 20: Documentation Android

Take a look at the DBHelper class — this class is provided to encapsulate data

access to a SQLite database that will hold our notes data and allow us to update it.

Typically you would implement this using a ContentProvider, and in fact the full

Notepad application included with the SDK does implement such a

ContentProvider. However, there is no reason you can't just use your own SQLite

database directly as we do here. The main thing to notice about this class is that it

takes care of the details of storing, retrieving and updating data in the SQLite

database for us. There are methods for retrieving all the rows, retrieving a row

based on rowIds, creating a new row, deleting an existing row and updating a row.

If you want a quick primer in how to use the SQLite Database for your own

applications, either take a look at this class or better yet, look at the full Notepad

application included with the SDK in the samples/ folder as the sample uses a ContentProvider.

Open the notepad_list.xml file in res/layout and take a look at it:

This is a layout definition file with a default starting point in it, we have provided

this as a convenience to get you going quickly.

All Android layout files must start with the XML header line: <?xml a.

Step 2

For this exercise, we are just going to use

a SQLite database directly to store our

data, but in a real application it would be

much better to write a proper

ContentProvider to encapsulate this

behavior instead.

If you are interested, you can find out

more about content providers or the

whole subject of Storing, Retrieving, and

Exposing Data.

Accessing and modifying data

Step 3

Most Activities will have a layout

associated with them. The layout will be

the "face" of the activity to the user. In

this case our layout will take over the

Layouts and activities

version="1.0" encoding="utf-8"?>.

Also, the next definition will often (but not always) be a layout definition of

some kind, in this case a LinearLayout.

b.

Note also that the xml namespace of Android should always be defined in

the top level component or layout in the XML so that android: tags can be

used through the rest of the file:

xmlns:android="http://schemas.android.com/apk/res/android"

c.

whole screen and provide a list of notes.

Full screen layouts are not the only option

for an Activity however. You might also

want to use a floating layout (for example,

a dialog or alert), or perhaps you don't

need a layout at all (the activity will be

invisible to the user unless you specify

some kind of layout for it to use).

We need to create the layout to hold our list. Add code inside of the LinearLayout tag so the whole file looks like this: (you

may have to hit the Source tab in order to edit the XML file)

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

<ListView id="@id/android:list"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

<TextView id="@id/android:empty"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/no_notes"/>

</LinearLayout>

Step 4

The ListView and TextView can be thought as two alternative views, only one of which will be displayed at once.

ListView will be used when there are notes to be shown, while the TextView (which has a default value of "No Notes

Yet!" defined as a string resource, will be displayed if there aren't any notes to display).

a.

The @ in the id strings of the ListView and TextView means that the XML parser should parse and expand the rest of

the id string and use an ID resource.

b.

19Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 21: Documentation Android

To make a list view, we also need to define a view for each row in the list:

Create a new file under res/layout called notes_row.xml.a.

Add the following contents (note: again the xml header is used, and the

first node defines the Android xml namespace)

<?xml version="1.0" encoding="utf-8"?>

<TextView id="@+id/text1"

xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"/>

b.

This is the view that will be used for each notes title row — it has only one text field in it.c.

Step 5

The folders under res/ in the Eclipse

project are special. There is a specific

structure to the folders and files under

this folder.

In particular, resources defined in these

folders and files will have corresponding

entries in the R class allowing them to be

easily accessed and used from your

application. Furthermore, they will be

bundled and deployed as part of the

application.

Resources and the R class

..

And, the android:list and android:empty are IDs that are already provided for us by the Android platform,

empty is used automatically when no data is provided in the l ist adapter. The List Adapter knows to look for these

names specifically by default. Alternatively you could also choose to change the default empty view used by the List

Adapter by using the setEmptyView().

More broadly, the android.R class is a set of predefined resources provided for you by the platform, while your

project's R class is the set of resources your project has defined. Resources found in the android.R resource class

can be used in the XML files by using the android: name space prefix (as we see here).

c.

In this case we create a new id called text1. The + after the @ in the id string indicates that the id should be

automatically created if it does not already exist, so we are defining text1 on the fly and then using it.

d.

After saving this file, open the R.java class in the project and look at it, you should see new definitions for

notes_row and text1 (our new definitions) meaning we can now gain access to these from the our code.

e.

Next, open the Notepadv1 class in the source. We are going to alter this class to become a list adapter and display our

notes, and also allow us to add new notes

Notepadv1 will be a subclass of Activity called a ListActivity, which has extra functionality to accommodate the

kinds of things you might want to do with a list, for example: displaying an arbitrary number of list items in rows on the

screen, moving through the list items, and allowing them to be selected.

Take a look through the existing code in Notepadv1 class. There are some constant definitions at the top, followed by a

private field we will use to create numbered note titles, and some overrides of methods from the superclass.

Step 6

Change the inheritance of Notepadv1 from Activity to ListActivity:

public class Notepadv1 extends ListActivity

Note: you will have to import ListActivity into the Notepadv1 class using Eclipse, ctrl-shift-O on Windows or Linux, or

cmd-shift-O on the Mac (organize imports) will do this for you.

Step 7

There are already three override methods defined: onCreate, onCreateOptionsMenu and onOptionsItemSelected,

we need to fill these out:

onCreate() is called when the activity is started — it is a little like the "main" method for the activity. We use this to

set up resources and state for the activity when it is running

onCreateOptionsMenu() is used to populate the menu for the activity. This is shown when the user hits the menu

button, and has a list of options they can select (like "Create Note")

onOptionsItemSelected() is the other half of the menu equation, it is used to handle events generated from the

menu (e.g. when the user selects the "Create Note" item).

Step 8

20Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 22: Documentation Android

Fill out the body of the onCreate() method.

Here we will set the title for the activity (shown at the top of the screen), use the notepad_list layout we have created for

the activity display contents, set up the DBHelper instance we will use to access notes data, then populate the list with the

available note titles:

call super() with the icicle parameter passed into our methoda.

setContentView to R.layout.notepad_listb.

Create a new private class field called dbHelper of class DBHelper (before the onCreate method)c.

Back in the onCreate method, construct a DBHelper instance — assign to the dbHelper field (note, you must pass

this into the constructor for DBHelper)

d.

Finally, call a new method -fillData()- gets the data and populates it using the helper, we haven't defined it yete.

onCreate() should now look like this:

@Override

public void onCreate(Bundle icicle)

f.

Step 9

{

super.onCreate(icicle);

setContentView(R.layout.notepad_list);

dbHelper = new DBHelper(this);

fillData();

}

And remember to add the DBHelper field definition (right under the noteNumber definition):

private DBHelper dbHelper;

Fill out the body of the onCreateOptionsMenu() method.

We are going to add just one menu item for now, "Add Item", using a string we will

create in strings.xml, and defined with a constant we will create at the top of the

class to identify the Add Item operation.

In strings.xml resource (under res/values), add a new string for

menu_insert with text "Add Item"

<string name="menu_insert">Add Item</string>, then save the

file

a.

Also, you need a menu position constant at the top of the Notepadv1 class (right under the KEY_BODY definition):

public static final int INSERT_ID = Menu.FIRST;

b.

In the onCreateOptionsMenu() method, add the menu item. Also take care of the result of the super call being

returned. The whole method should now look like this:

@Override

public boolean onCreateOptionsMenu(Menu menu) {

boolean result = super.onCreateOptionsMenu(menu);

menu.add(0, INSERT_ID, R.string.menu_insert);

return result;

}

c.

Step 10

The notepad application we are

constructing only scratches the surface

with menus.

You can also add shortcut keys for menu

items, create submenus and even add

menu items to other applications!.

More on menus

21Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 23: Documentation Android

Fill out the body of the onOptionsItemSelected() method:

This is going to handle our new "Add Note" menu item. When this is selected the onOptionsItemSelected() method will

be called with the item.getId() set to INSERT_ID (the constant we used to identify the menu item). We can detect this,

and take the appropriate actions:

The super.onOptionsItemSelected(item) method call goes at the end of this method — we want to catch our

events first!

a.

Switch statement on item.getId()b.

case INSERT_ID:c.

calls new method createNote()d.

break at the end of the casee.

return the result of the superclass onOptionsItemSelected() method at the endf.

The whole onOptionsItemSelect() method should now look like this:

@Override

g.

Step 11

public boolean onOptionsItemSelected(Item item) {

switch (item.getId()) {

case INSERT_ID:

createNote();

break;

}

return super.onOptionsItemSelected(item);

}

Add a new createNote() method:

In this first version of our application, createNote() is not going to be very useful. We will simply create a new note with a

title assigned to it based on a counter ("Note 1", "Note 2"...) and with an empty body. At present we have no way of editing

the contents of a note, so for now we will have to be content making one with some default values:

String noteName = "Note " + noteNumber++; (Construct the name using "Note" and the counter we have

defined in the class)

a.

Call dbHelper.createRow() using noteName as the title and "" for the bodyb.

Call fillData() method again after adding (inefficient but simple)c.

The whole createNote() method should look like this:

private void createNote() {

String noteName = "Note " + noteNumber++;

dbHelper.createRow(noteName, "");

fillData();

}

d.

Step 12

22Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 24: Documentation Android

Define the fillData() method. This is fairly long:

This method uses ArrayAdapter, which is the simplest way of putting data into

a ListView. ArrayAdapter takes either a List or an array of Strings, and binds

them into a text view provided in the layout defined for the list row (this is the

text1 field in our notes_row.xml layout). The method simply obtains a list of

notes from the database helper, constructs a List of Strings using the title strings

from each row, and then creates an ArrayAdapter out of those items and

bound to use the notes_row we defined.

private void fillData() {

// We need a list of strings for the list items

List<String> items = new ArrayList<String>();

// Get all of the rows from the database and create the item list

List<Row> rows = dbHelper.fetchAllRows();

for (Row row : rows) {

items.add(row.title);

}

// Now create an array adapter and set it to display using our row

ArrayAdapter<String> notes =

new ArrayAdapter<String>(this, R.layout.notes_row, items);

Step 13

Our example uses a very simple array

adapter which binds an array or list of

items into a ListView. More commonly in

Android, List Adapters go hand in hand

with ContentProviders, and this is also a

very easy way to use lists.

To bind a ContentProvider to a ListView

you can use a

android.widget.SimpleCursorAdapter to

bind data from a ContentProvider into a

ListView

List adapters

setListAdapter(notes);

}

ArrayAdapter needs a List of Strings (List<String>) containing the items to displaya.

The data is read out of the database as rows, and the title field from each row is used to populate the list of stringsb.

We specify the notes_row view we created as the receptacle for the datac.

If you get compiler errors about classes not being found, ctrl-shift-O or (cmd-shift-O on the mac) to organize imports.d.

Note: that for this exercise we use an ArrayAdapter, this is not a very scalable solution and more typically a

SimpleCursorAdapter would be used with a ContentProvider or at least a Cursor returned from a query. See the

sidebar on List Adapters for more information.

Run it!

Right click on the Notepadv1 projecta.

From the popup menu, select Run As -> Android Applicationb.

If you see a dialog come up, select Android Launcher as the way of running the application (you can also use the link

near the top of the dialog to set this as your default for the workspace, this is recommended as it will stop the plugin

from asking you this every time)

c.

Add new notes by hitting the menu button and selecting Add Item from the menud.

You can see the solution to this class in Notepadv1Solution from the zip file to compare with your own.

Once you are ready, move on to Tutorial Exercise 2 to add the ability to create, edit and delete notes.

Step 14

Solution and Next Steps

23Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 25: Documentation Android

In this exercise, you will add a second activity to your notepad application, to let the user create, edit, and delete notes. The

new activity assumes responsibility for creating new notes by collect ing user input and packing it into a return bundle

provided by the intent. This exercise demonstrates:

Constructing a new activity and adding it to the Android manifest

Invoking another activity asynchronously using startSubActivity()

Passing data between activites in bundles

How to use a more advanced screen layout

Import the existing Notepadv2 project from under the NotepadCodeLab folder. If you see an error about

AndroidManifest.xml, or some problems related to an android.zip file, right click on the project and select Android

Tools->Fix Project Properties from the popup menu.

Open the Notepadv2 project and take a look around:

Open and look at the strings.xml file under res/values — there are several new strings which we will use for our

new functionality

a.

Also, open and take a look at the top of the Notepadv2 class, you will notice some new stuff in there as well —

several new constants have been defined, as well as a member field for rows (to hold row data for the list)

b.

Note also that the fillData() method has been altered slightly to use this rows field instead of a local variablec.

There are also a couple of new overridden methods ( onListItemClick() and onActivityResult()) which we

will be filling in below.

d.

Check the onCreate() method, you will see that it is unchanged from what we wrote in the first exercise.

We need to add a delete entry into the menu:

In the onCreateOptionsMenu() method, add a new line:

menu.add(0, DELETE_ID, R.string.menu_delete);

a.

The whole method should now look like this:

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

menu.add(0, INSERT_ID, R.string.menu_insert);

menu.add(0, DELETE_ID, R.string.menu_delete);

return true;

}

b.

Tutorial: Notepad Exercise 2

Step 1

Step 2

Step 3

24Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 26: Documentation Android

In the onMenuItemSelected() method, add a new case for DELETE_ID:

dbHelper.deleteRow(rows.get(getSelection()).rowId);

fillData();

break;

This uses the getSelection() method from the ListActivity to see

what note is currently selected from the list

a.

It then looks that row up from the rows field we have been holding on to,

and gets the rowId, and uses it to delete the row using the DBHelper

b.

We fill data afterwards to keep everything up to datec.

The whole method should now look like this:

@Override

public boolean onMenuItemSelected(int featureId, Item item) {

super.onMenuItemSelected(featureId, item);

switch(item.getId()) {

case INSERT_ID:

createNote();

fillData();

break;

case DELETE_ID:

dbHelper.deleteRow(rows.get(getSelection()).rowId);

fillData();

break;

}

return true;

}

d.

Fill in the body of the createNote() method:

We will create a new Intent to create a note (ACTIVITY_CREATE) using the NoteEdit class. We then fire the Intent

using the startSubActivity() method call.

Intent i = new Intent(this, NoteEdit.class);

startSubActivity(i, ACTIVITY_CREATE);

Don't worry about the fact that NoteEdit doesn't exist yet, we will fix that soon.

Note: in this example our Intent uses a class name specifically. While this makes sense sometimes, it is more common

to call an Intent using an action and contentURI. See android.content.Intent for more information.

Fill in the body of the onListItemClick() override.

onListItemClick() is the overridden method that is called when the user selects an item from the list. It is passed four

parameters: the ListView object it was invoked from, the View inside the ListView that was clicked on, the position in

the list that was clicked, and the rowId of the item that was clicked. In this instance we can ignore the first two parameters

(we only have one ListView it could be), and we ignore the rowId as well. All we are interested in is the position that

the user selected. We use this to get the data from the correct row, and bundle it up to send in to the NoteEdit activity.

Step 4

As well as starting intents in classes we

already know about, be they in our own

application or another application, we can

also create intents without knowing

exactly which application will handle it.

For example, we might want to open a

page in a browser, and for this we still

use an intent. But instead of specifying a

class to handle it, we use a predefined

Intent constant, and a content URI that

describes what we want to do.

Starting Other Activities

Step 5

Step 6

25Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 27: Documentation Android

This method creates an Intent to edit the note using the NoteEdit class. It then adds data into the extras bundle in the

Intent, which can be used to pass information into the Intent. We use it to pass in the title and body text, and the rowId for

the note we are editing. Finally, it will fire the Intent using the startSubActivity() method call.

super.onListItemClick(l, v, position, id);

Intent i = new Intent(this, NoteEdit.class);

i.putExtra(KEY_ROW_ID, rows.get(position).rowId);

i.putExtra(KEY_BODY, rows.get(position).body);

i.putExtra(KEY_TITLE, rows.get(position).title);

startSubActivity(i, ACTIVITY_EDIT);

This implementation uses an extras bundle available on the intent we are using to pass in the title, body and rowId of

the note we want to edit, then invokes the intent ACTIVITY_EDIT on the NoteEdit class

a.

putExtra() is the method to add items into the extras bundle to pass in to intent invocationsb.

The above createNote() and onListItemClick() methods use an asynchronous intent invocation. We need a

handler, so we fill in the body of the onActivityResult() override.

onActivityResult() is the overridden method which will be called when a sub activity returns. The parameters provided

are:

requestCode — the original request code specified in the Intent invocation (either ACTIVITY_CREATE or

ACTIVITY_EDIT for us)

resultCode — the result (or error code) of the call, this should be zero if everything was OK, but may have a

non-zero code indicating that something failed. There are standard result codes available, and you can also create

your own constants to indicate specific problems

data — this is a simple string that can be used to hold some kind of textual return information (for example, the result

of the user typing something into a dialog). This is useful if you only have one thing to return, and it happens to be a

string, if you need to return more, use the extras bundle instead

extras — this is the returned extras bundle (if any) provided by the called Intent

The combination of startSubActivity() and onActivityResult() can be thought of as an asynchronous RPC

(remote procedure call) and forms the recommended way for Activities to invoke each other and share services.

super.onActivityResult(requestCode, resultCode, data, extras);

switch(requestCode) {

case ACTIVITY_CREATE:

String title = extras.getString(KEY_TITLE);

String body = extras.getString(KEY_BODY);

dbHelper.createRow(title, body);

fillData();

break;

case ACTIVITY_EDIT:

Long rowId = extras.getLong(KEY_ROW_ID);

if (rowId != null) {

String editTitle = extras.getString(KEY_TITLE);

String editBody = extras.getString(KEY_BODY);

dbHelper.updateRow(rowId, editTitle, editBody);

}

fillData();

break;

}

We are handling both the ACTIVITY_CREATE and ACTIVITY_EDIT activity results in this methoda.

In the case of a create, we pull the title and body from the extras and use them to create a new noteb.

In the case of an edit, we pull the rowId as well, and use that to update the note in the databasec.

Step 7

fillData() at the end ensures everything is up to dated.

26Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 28: Documentation Android

Open the file note_edit.xml that has been provided and take a look at it. This

is the UI code for the Note Editor.

This is the most sophisticated UI we have dealt with yet. The file is given to you to

avoid problems that may sneak in when typing the code in (the XML is very strict

about case sensitivity and structure, mistakes in these are the usual cause of

problems with layout XML files).

There is a new parameter used here that we haven't seen before:

android:layout_weight (in this case set to use the value 1).

layout_weight is used in LinearLayouts to assign "importance" to views within

the layout. All views have a default layout_weight of zero, meaning they take

up only as much room on the screen as they need to be displayed. Assigning a

value higher than zero will split up the rest of the available space in the parent

according to the value of the view's layout_weight and its ratio to the overall

layout_weight specified in the current layout for this and other views.

To give an example: let's say we have a text label and two text edit views in a horizontal row. The label has no

layout_weight specified, so it takes up the minimum space required to render. If the layout_weight of each of the two

text edit views is set to 1, the remaining width in the parent layout will be split equally between them. If one has a

layout_weight of 1 and the other has a layout_weight of 2, then one third of the remaining space will be given to the

first, and two thirds to the second.

This layout also demonstrates how to nest multiple layouts inside each other to achieve a more complex and pleasant

layout. In this example, a horizontal linear layout is nested inside the vertical one to allow the title label and text field to be

alongside each other horizontally.

Create a NoteEdit class that extends android.app.Activity.

This is the first time we will have created an activity without the Android Eclipse plugin doing it for us. When you do so, the

onCreate() method is not automatically overridden for you. It is hard to imagine an activity that doesn't override the

onCreate() method, so this should be the first thing you do (there is an override/implement methods option available from

the right click popup menu in the eclipse editor that we will use)

Right click on the com.google.android.demo.notepad2 package in the Package Explorer, and select

New->Class from the popup menu

a.

Fill in NoteEdit for the Name: field in the dialogb.

In the Superclass: field, enter android.app.Activity (you can also just type Activity and hit Ctrl-Space on

Windows and Linux or Cmd-Space on the Mac, to invoke code assist and find the right package and class)

c.

Hit the Finish buttond.

In the resulting NoteEdit class, right click in the editor window and select Source->Override/Implement

Methods...

e.

Scroll down through the checklist in the dialog until you see onCreate(Bundle) — and check the box next to itf.

Hit the OK button.g.

Fill in the body of the onCreate() method.

This will set the title of our new activity to say "Edit Note" (one of the strings defined in strings.xml). It will also set the

content view to use our note_edit.xml layout file. We can then grab handles to the title and body text edit views, and the

confirm button, so that our class can use them to set and get the note title and body, and attach an event to the confirm

Step 8

The provided note_edit.xml layout file is

the most sophisticated one in the

application we will be building, but that

doesn't mean it is even close to the kind

of sophistication you will be likely to want

in real Android applications.

Creating a good UI is part art and part

science, and the rest is work. Mastering

Android layout is an essential part of

creating a good looking Android

application.

Take a look at the View Gallery for some

example layouts and how to use them.

The ApiDemos sample project is also a

great resource from which to learn how to

create different layouts.

The Art of Layout

Step 9

Step 10

button for when it is pressed by the user.

27Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 29: Documentation Android

We can then unbundle the values that were passed in to the activity from the extras bundle in the calling Intent, and use

those to pre-populate the title and body text edit views with data so that the user can edit them. We will grab and store the

rowId as well so that we can keep track of what note the user is editing.

Set up the layout:

setContentView(R.layout.note_edit);

a.

Find the edit and button components we need:

These are found by the IDs associated to them in the R class, and need to be cast to the right type of View

(EditText for the two text views, and Button for the confirm button)

titleText = (EditText) findViewById(R.id.title);

bodyText = (EditText) findViewById(R.id.body);

Button confirmButton = (Button) findViewById(R.id.confirm);

Note that titleText and bodyText are member fields (you will need to add them at the top of the class definition)

b.

Create a Long rowId private field which will be used to store the current rowId being edited (if any)c.

Add code to initialize the title, body and rowId from the extras bundle in the intent, if it is present:

rowId = null;

Bundle extras = getIntent().getExtras();

if (extras != null) {

String title = extras.getString(Notepadv2.KEY_TITLE);

String body = extras.getString(Notepadv2.KEY_BODY);

rowId = extras.getLong(Notepadv2.KEY_ROW_ID);

if (title != null) {

titleText.setText(title);

}

if (body != null) {

bodyText.setText(body);

}

}

We are pulling the title and body out of the extras bundle that was set from the Intent invocation

Have to null-protect the text field setting (i.e. we don't want to set the text fields to null accidentally)

d.

Create an onClickListener() for the button:

Listeners can be one of the more confusing aspects of UI implementation, but what we are trying to achieve in this

case is simple. We simply want an onClick() method to be called when the user presses the confirm button, and we

can use that to do some work and return the values of the edited note to the Intent caller. We do this using something

called an anonymous inner class. This is a bit confusing to look at unless you have seen them before, but all you really

need to take away from this is that you can refer to this code in the future to see how to create a listener and attach it

to a button. (Listeners are a common idiom in Java development, particularly for user interfaces.)

confirmButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

}

});

e.

28Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 30: Documentation Android

Fill in the body of the onClick() method.

This is the code that will be run when the user clicks on the confirm button. We want this to grab the title and body text from

the edit text fields, and put them into the return bundle so that they can be passed back to the activity that invoked this Intent

in the first place. If the operation is an edit rather than a create, we also want to put the rowId into the bundle as well so that

the Notepadv2 class can save the changes back to the correct note.

Create a bundle and put the title and body text into it using the constants defined in Notepadv2 as keys

Bundle bundle = new Bundle();

bundle.putString(Notepadv2.KEY_TITLE, titleText.getText().toString());

bundle.putString(Notepadv2.KEY_BODY, bodyText.getText().toString());

if (rowId != null) {

bundle.putLong(Notepadv2.KEY_ROW_ID, rowId);

}

a.

Set the result information, including the bundle, and finish the activity:

The setResult() method is used to set the result code, return data string, and extras bundle to be passed back to

the Intent caller. In this case everything worked, so we return RESULT_OK for the result code. We are not using the

string data field in this case, so we pass a null back for that and pass the bundle we have just created with the title,

body and rowId information in it.

The finish() call is used to signal that the activity is done (like a return call). Anything set in the Result will then be

returned to the caller, along with execution control.

setResult(RESULT_OK, null, bundle);

finish();

b.

The full onCreate() method (plus supporting class fields) should now look like this:

private EditText titleText;

private EditText bodyText;

private Long rowId;

@Override

protected void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.note_edit);

titleText = (EditText) findViewById(R.id.title);

bodyText = (EditText) findViewById(R.id.body);

Button confirmButton = (Button) findViewById(R.id.confirm);

rowId = null;

Bundle extras = getIntent().getExtras();

if (extras != null) {

String title = extras.getString(Notepadv2.KEY_TITLE);

String body = extras.getString(Notepadv2.KEY_BODY);

rowId = extras.getLong(Notepadv2.KEY_ROW_ID);

if (title != null) {

titleText.setText(title);

}

if (body != null) {

bodyText.setText(body);

}

}

c.

Step 11

29Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 31: Documentation Android

confirmButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

Bundle bundle = new Bundle();

bundle.putString(Notepadv2.KEY_TITLE,

titleText.getText().toString());

bundle.putString(Notepadv2.KEY_BODY, bodyText.getText().toString());

if (rowId != null) {

bundle.putLong(Notepadv2.KEY_ROW_ID, rowId);

}

setResult(RESULT_OK, null, bundle);

finish();

}

});

}

Finally the new activity has to be defined in the manifest file:

Before the new activity can be seen by Android, it needs its own activity entry in

the AndroidManifest.xml file. This is to let the system know that it is there

and can be called. We could also specify which IntentFilters the activity

implements here, but we are going to skip this for now and just let Android know

that the Activity is defined.

<activity class=".NoteEdit"/>

This should be placed just below the line that reads </activity> for the

.Notepadv2 activity.

Now Run it! (use Run As -> Android Application on the project right click menu again)

You should now be able to add real notes from the menu, as well as deleting an existing one using the menu. Furthermore,

selecting a note title from the list should bring up the note editor to let you edit it. Hit confirm when finished to save the

changes back to the database.

You can see the solution to this exercise in Notepadv2Solution from the zip file to compare with your own.

Now try editing a note, and then hitting the back button on the emulator instead of the confirm button (the back button is

below the menu button). You will see an error come up. Clearly our application still has some problems. Worse still, if you

did make some changes and hit the back button, when you go back into the notepad to look at the note you change, you will

find that all your changes have been lost. In the next exercise we will fix these problems.

Once you are ready, move on to Tutorial Exercise 3 where you will fix the problems with the back button and lost edits by

introducing a proper life cycle into the NoteEdit Activity.

Step 12

The AndroidManifest.xml file is the way in

which Android sees your application. This

file defines the category of the

application, where it shows up (or even if

it shows up) in the launcher or settings,

what activities, services, and content

providers it defines, what intents it can

receive, and more.

For more information, see the reference

document AndroidManifest.xml

The All-Important Android Manifest

File

Step 13

Solution and Next Steps

30Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 32: Documentation Android

In this exercise, you will use life-cycle event callbacks to store and retrieve application state data. This exercise

demonstrates:

Life-cycle events and how your application can use them

Techniques for maintaining application state

The current example has some problems — hitting the back button when editing causes a crash, and anything else that

happens during editing will cause the edits to be lost.

To fix this, we will move most of the functionality for creating and editing the note into the NoteEdit class, and introduce a full

lifecycle for editing notes.

Import Notepadv3 into Eclipse. If you see an error about AndroidManifest.xml, or some problems related to an

Android zip file, right click on the project and select Android Tools->Fix Project Properties from the popup menu. The starting

point for this exercise is exactly the same as the solution for Notepadv2.

Remove the NoteEdit code to parse out the title and body from the extras bundle.

We are going to use the DBHelper class to access the notes from the database directly. All we need passed into the

activity is a rowId (if we are editing, if creating we don't need anything). We will get rid of the properties that were

being passed in through the extras bundle that we were using to set the title and body text edit values in the UI.

a.

Remove the lines that read:

String title = extras.getString(Notepadv3.KEY_TITLE);

String body = extras.getString(Notepadv3.KEY_BODY);

and

if (title != null) {

titleText.setText(title);

}

if (body != null) {

bodyText.setText(body);

}

(Extra credit, you could replace the remaining if (extras != null) block with a ternary operator as well:

rowId = extras != null ? extras.getLong(Notepadv3.KEY_ROW_ID) : null;

b.

Create a class field for a DBHelper at the top of the class:

private DBHelper dbHelper;

and an instance of DBHelper in the onCreate() method (right below the super.onCreate() call):

Tutorial: Notepad Exercise 3

Step 1

Step 2

dbHelper = new DBHelper(this);

31Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 33: Documentation Android

We need to check the icicle for a rowId in case the note editing has been frozen and thawed:

Replace the code that currently initializes the rowId:

rowId = null;

Bundle extras = getIntent().getExtras();

if (extras != null) {

rowId = extras.getLong(Notepadv3.KEY_ROW_ID);

}

with

rowId = icicle != null ? icicle.getLong(Notepadv3.KEY_ROW_ID) : null;

if (rowId == null) {

Bundle extras = getIntent().getExtras();

rowId = extras != null ? extras.getLong(Notepadv3.KEY_ROW_ID) : null;

}

a.

Note the null check for icicle, and we still need to load up rowId from the extras bundle if it is not provided by the

icicle. This is a ternary operator shorthand to safely either use the value or null if it is not present.

b.

Next, we need to populate the fields based on the rowId if we have it:populateFields();

before the confirmButton.setOnClickListener() line.

Get rid of the bundle creation and bundle value settings from the onClick() handler method. The Activity no longer needs

to return any extra information to the caller. You can also use the shorter version of setResult():

public void onClick(View arg0) {

setResult(RESULT_OK);

finish();

}

We will take care of storing the updates or new notes in the database ourselves using the lifecycle methods.

The whole onCreate() method should now look like this:

super.onCreate(icicle);

dbHelper = new DBHelper(this);

setContentView(R.layout.note_edit);

titleText = (EditText) findViewById(R.id.title);

Step 3

Step 4

Step 5

bodyText = (EditText) findViewById(R.id.body);

Button confirmButton = (Button) findViewById(R.id.confirm);

32Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 34: Documentation Android

populateFields();

confirmButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View arg0) {

setResult(RESULT_OK);

finish();

}

});

Define the populateFields() method.

private void populateFields() {

if (rowId != null) {

DBHelper.Row row = dbHelper.fetchRow(rowId);

if (row.rowId > -1) {

titleText.setText(row.title);

bodyText.setText(row.body);

}

}

}

Override methods onFreeze(), onPause() and onResume()

These are our lifecycle methods (along with onCreate() which we already have).

onFreeze() is called by Android if the Activity is being stopped and may be

killed before it is resumed! This means it should store any state necessary to

re-initialize to the same condition when the activity is restarted. It is the

counterpart to the onCreate() method, and in fact the icicle bundle passed

in to onCreate() is the same bundle that you construct as outState in the

onFreeze() method.

onPause() and onResume() are also complimentary methods. onPause() is

always called when the Activity ends, even if we instigated that (with a finish call

for example). We will use this to save the current note back to the database.

Good practice is to release any resources that can be released during an

onPause() as well, to take up less resources when in the passive state. For this

reason we will close the DBHelper class and set the field to null so that it can be

garbage collected if necessary. onResume() on the other hand, will re-create

the dbHelper instance so we can use it, and then read the note out of the

database again and populate the fields.

Step 6

Step 7

If you are used to always having control

in your applications, you might not

understand why all this lifecycle work is

necessary. The reason is that in Android,

you are not in control of your activity, the

operating system is!

As we have already seen, the Android

model is based around Activities calling

each other. When one Activity calls

another, the current activity is paused at

the very least, and may be killed

altogether if the system starts to run low

on resources. If this happens, your

Activity will have to store enough state to

come back up later, preferably in the

same state it was in when it was killed.

Android has a well-defined lifecycle.

Lifecycle events can happen even if you

are not handing off control to another

Why handling lifecycle events is

important

rowId = icicle != null ? icicle.getLong(Notepadv3.KEY_ROW_ID) : null;

if (rowId == null) {

Bundle extras = getIntent().getExtras();

if (extras != null) {

rowId = extras.getLong(Notepadv3.KEY_ROW_ID);

}

}

activity explicitly. For example, perhaps a

call comes in to the handset. If this

happens, and your activity is running, it

will be swapped out while the call activity

takes over.

33Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 35: Documentation Android

onFreeze():

@Override

protected void onFreeze(Bundle outState) {

super.onFreeze(outState);

outState.putLong(Notepadv3.KEY_ROW_ID,

rowId);

}

a.

onPause():

@Override

protected void onPause() {

super.onPause();

saveState();

dbHelper.close();

dbHelper = null;

}

b.

onResume():

@Override

protected void onResume() {

super.onResume();

if (dbHelper == null) {

dbHelper = new DBHelper(this);

}

populateFields();

}

c.

Define the saveState() method to put the data out to the database.

private void saveState() {

String title = titleText.getText().toString();

String body = bodyText.getText().toString();

if (rowId == null) {

dbHelper.createRow(title, body);

} else {

dbHelper.updateRow(rowId, title, body);

}

}

Now pull out the previous handling code from the onActivityResult() method in the Notepadv3 class

All of the note retrieval and updating now happens within the NoteEdit lifecycle, so all the onActivityResult() method

needs to do is update its view of the data, no other work is necessary. The resulting method should look like this:

@Override

protected void onActivityResult(int requestCode, int resultCode,

String data, Bundle extras) {

Step 8

Step 9

super.onActivityResult(requestCode, resultCode, data, extras);

fillData();

}

Because the other class now does the work, all this has to do is refresh the data.

34Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 36: Documentation Android

Also remove the lines which set the title and body from the onListItemClick() method (again they are no longer

needed, only the rowId is):

i.putExtra(KEY_TITLE, rows.get(position).title);

i.putExtra(KEY_BODY, rows.get(position).body);

Run it! (use Run As -> Android Application on the project right click menu again)

You can see the solution to this exercise in Notepadv3Solution from the zip file to compare with your own.

When you are ready, move on to the Tutorial Extra Credit exercise, where you can use the Eclipse debugger to examine the

lifecycle events as they happen.

Step 10

Solution and Next Steps

In this exercise, you will use the debugger to look at the work you did in Exercise 3. This exercise demonstrates:

How to set breakpoints to observe execution

How to run your application in debug mode

Using the working Notepadv3, put breakpoints in the code at the beginning of the onCreate(), onPause(), onFreeze()

and onResume() methods in the NoteEdit class (if you are not familiar with Eclipse, just right click in the narrow grey

border on the left of the edit window at the line you want a breakpoint, and select Toggle Breakpoint, you should see a blue

dot appear).

Now start the notepad demo in debug mode:

Right click on the Notepadv3 project and from the Debug menu select Debug As -> Android Application.a.

The Android emulator should say "waiting for debugger to connect" briefly and then run the application.b.

If it gets stuck on the waiting... screen, quit the emulator and Eclipse, from the command line do an adb

kill-server, and then restart Eclipse and try again.

c.

When you edit or create a new note you should see the breakpoints getting hit and the execution stopping.

Hit the Resume button to let execution continue (yellow rectangle with a green triangle to its right in the Eclipse toolbars near

the top).

Experiment a bit with the confirm and back buttons, and try hitting home and making other mode changes. Watch what

lifecycle events are generated and when.

The Android Eclipse plugin not only offers excellent debugging support for your application development, but also superb

profiling support. If your application is running too slow, this can help you find the bottlenecks and fix them.

Tutorial: Extra Credit

Step 1

Step 2

Step 3

Step 4

Step 5

35Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 37: Documentation Android

Creating an Android Application using the Eclipse plugin

Creating an Android Application without the Eclipse plugin

Implementing Activity callbacks (Android calls your activity at various key moments in its lifecycle. You must know how

to handle each of these to draw your screen, initialize class members, and acquire data.)

Opening a new screen

Listening for button clicks

Configuring general window properties

Storing and retrieving state

Storing and retrieving preferences

Storing and retrieving larger or more complex persistent data (files and data)

Playing audio, video, still, or other media files

Listening for and broadcasting global messages and setting alarms

Displaying alerts

Displaying a progress bar

Adding your application to the Favorites list

Adding items to the screen menu

Display a web page

Binding to data

Capture images from the phone camera

Handling expensive operations in the UI thread

Selecting, highlighting, or styling portions of text

List of files for an Android application

The ApiDemos sample application includes many, many examples of common tasks and UI features. See the code

inside samples/ApiDemos and the other sample applications under the samples/ folder in the SDK.

Using the Android Eclipse plugin is the fastest and easiest way to start creating a new Android application. The plugin

automatically generates the correct project structure for your application, and keeps the resources compiled for you

automatically.

It is still a good idea to know what is going on though. Take a look at Overview of an Android Application to understand the

basics of how an Android application works.

It is also recommended that you take a look at the ApiDemos application and the other sample applications in the samples/

folder in the SDK.

Finally, a great way to started with Android development in Eclipse is to follow both the Hello Android and Notepad code

tutorials. In particular, the start of the Hello Android tutorial is an excellent introduction to creating a new Android application

in Eclipse.

This topic describes the manual steps in creating an Android application. Before reading this, you should read Overview of

an Android Application to understand the basics of how an Android application works. You might also want to look at the

sample applications that ship with Android under the samples/ directory.

Common Tasks and How To Do Them in Android

Creating an Android Application using the Eclipse Plugin

Creating an Android Application without the Eclipse Plugin

36Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 38: Documentation Android

Here is a list of the basic steps in building an application.

Create your required resource files This includes the AndroidManifest.xml global description file, string files that

your application needs, and layout files describing your user in terface. A full list of optional and required files and

syntax details for each is given in File List for an Android Application.

1.

Design your user interface See Implementing a UI for details on elements of the Android screen. 2.

Implement your Activity (this page) You will create one class/file for each screen in your application. Screens will

inherit from an android.app class, typically android.app.Activity for basic screens, android.app.ListActivity for list

screens, or android.app.Dialog for dialog boxes. You will implement the required callbacks that let you draw your

screen, query data, and commit changes, and also perform any required tasks such as opening additional screens or

reading data from the device. Common tasks, such as opening a new screen or reading data from the device, are

described below. The list of files you'll need for your application are described in List of Files for an Android

Application.

3.

Build and install your package. The Android SDK has some nice tools for generating projects and debugging code.4.

Android calls a number of callbacks to let you draw your screen, store data before pausing, and refresh data after closing.

You must implement at least some of these methods. See Lifetime of a Screen to learn when and in what order these

methods are called. Here are some of the standard types of screen classes that Android provides:

android.app.Activity - This is a standard screen, with no specialization.

android.app.ListActivity - This is a screen that is used to display a list of something. It hosts a ListView object, and

exposes methods to let you identify the selected item, receive callbacks when the selected item changes, and perform

other list-related actions.

android.app.Dialog - This is a small, popup dialog-style window that isn't intended to remain in the history stack. (It is

not resizeable or moveable by the user.)

Your Activity will often need to open another Activity screen as it progresses. This new screen can be part of the same

application or part of another application, the new screen can be floating or full screen, it can return a result, and you can

decide whether to close this screen and remove it from the history stack when you are done with it, or to keep the screen

open in history. These next sections describe all these options.

When you open a new screen you can decide whether to make it transparent or floating, or full-screen. The choice of new

screen affects the event sequence of events in the old screen (if the new screen obscures the old screen, a different series

of events is called in the old screen). See Lifetime of an Activity for details.

Transparent or floating windows are implemented in three standard ways:

Create an app.Dialog class

Create an app.AlertDialog class

Set the Theme_Dialog theme attribute to @android:style/Theme.Dialog in your AndroidManifest.xml file. For

example:

<activity class="AddRssItem" android:label="Add an item"

android:theme="@android:style/Theme.Dialog"/>

Calling startActivity() or startSubActivity() will open a new screen in whatever way it defines itself (if it uses a floating theme it

will be floating, otherwise it will be full screen).

When you want to open a new screen, you can either explicitly specify the activity class to open, or you can let the operating

system decide which screen to open, based upon the data and various parameters you pass in. A screen is opened by

calling startActivity and passing in an Intent object, which specifies the criteria for the handling screen. To specify a specific

screen, call Intent.setClass or setClassName with the exact activity class to open. Otherwise, set a variety of values and

Implementing Activity Callbacks

Opening a New Screen

Floating or full?

Opening a Screen

37Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 39: Documentation Android

data, and let Android decide which screen is appropriate to open. Android will find one or zero Activities that match the

specified requirements; it will never open multiple activities for a single request. More information on Intents and how

Android resolves them to a specific class is given in the Intent topic.

The following snippet loads the com.google.android.samples.Animation1 class, and passes it some arbitrary data.:

Intent myIntent = new Intent();

myIntent.component = "com.google.android.samples.Animation1";

myIntent.putExtra("com.google.android.samples.SpecialValue", "Hello, Joe!"); //

key/value pair, where key needs current package prefix.

startActivity(myIntent);

The next snippet requests that a Web page be opened by specifying the VIEW action, and a URI data string starting with

"http://" schema:

Intent myIntent = new Intent(Intent.VIEW_ACTION,

ContentURI.create("http://www.google.com"));

Here is the intent filter from the AndroidManifest.xml file for com.google.android.browser:

<intent-filter>

<action value="android.intent.action.VIEW" />

<category value="android.intent.category.DEFAULT" />

<scheme value="http" />

<scheme value="https" />

<scheme value="file" />

</intent-filter>

Android defines a number of standard values, for instance the action constants defined by Intent. You can define custom

values, but both the caller and handler must use them. See the <intent-filter> tag description in AndroidManifest.xml File

Details for more information on the manifest syntax for the handling application.

A window can return a result after it closes. This result will be passed back into the calling Activity's onActivityResult()

method, which can supply an integer result code, a string of data, and a Bundle of arbitrary data, along with the request code

passed to startSubActivity(). Note that you must call the startSubActivity() method that accepts a request code parameter to

get this callback. The following code demonstrates opening a new screen and retrieving a result.

// Open the new screen.

public void onClick(View v){

// Start the activity whose result we want to retrieve. The

// result will come back with request code GET_CODE.

Intent intent = new Intent(this, com.example.app.ChooseYourBoxer.class);

startSubActivity(intent, CHOOSE_FIGHTER);

}

// Listen for results.

protected void onActivityResult(int requestCode, int resultCode,

String data, Bundle extras){

// See which child activity is calling us back.

switch (resultCode) {

case CHOOSE_FIGHTER:

// This is the standard resultCode that is sent back if the

// activity crashed or didn't doesn't supply an explicit result.

if (resultCode == RESULT_CANCELED){

myMessageboxFunction("Fight cancelled");

Some Intent examples

Returning a Result from a Screen

38Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 40: Documentation Android

}

else {

myFightFunction(data, extras);

}

default:

break;

}

}

// Class SentResult

// Temporary screen to let the user choose something.

private OnClickListener mLincolnListener = new OnClickListener(){

public void onClick(View v) {

Bundle stats = new Bundle();

stats.putString("height","6\'4\"");

stats.putString("weight", "190 lbs");

stats.putString("reach", "74\"");

setResult(RESULT_OK, "Lincoln", stats);

finish();

}

};

private OnClickListener mWashingtonListener = new OnClickListener() {

public void onClick(View v){

Bundle stats = new Bundle();

stats.putString("height","6\'2\"");

stats.putString("weight", "190 lbs");

stats.putString("reach", "73\"");

setResult(RESULT_OK, "Washington", Bundle);

finish();

}

};

An activity can remove itself from the history stack by calling Activity.finish() on itself, or the activity that opened the screen

can call Activity.finishSubActivity() on any screens that it opens to close them.

Button click and other UI event capturing are covered in Listening for UI Notifications on the UI Design page.

You can set a number of general window properties, such as whether to display a title, whether the window is floating, and

whether it displays an icon, by calling methods on the Window member of the underlying View object for the window.

Examples include calling getWindow().requestFeature() (or the convenience method

requestWindowFeature( some_feature)) to hide the title. Here is an example of hiding the title bar:

//Hide the title bar

requestWindowFeature(Window.FEATURE_NO_TITLE);

If your application is dumped from memory because of space concerns, i t will lose all user interface state information such

as checkbox state and text box values as well as class member values. Android calls Activity.onFreeze before it pauses the

application. This method hands in a Bundle that can be used to store name/value pairs that will persist and be handed back

to the application even if it is dropped from memory. Android will pass this Bundle back to you when it calls onCreate(). This

Lifetime of the new screen

Listening for Button Clicks

Configuring General Window Properties

Storing and Retrieving State

39Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 41: Documentation Android

Bundle only exists while the application is still in the history stack (whether or not it has been removed from memory) and will

be lost when the application is finalized. See the topics for onFreeze(Bundle) and onCreate(Bundle) for examples of storing

and retrieving state.

Read more about the life cycle of an application in Lifetime of an Activity.

Your application can store files or complex collection objects, and reserve them for private use by itself or other activities in

the application, or it can expose its data to all other applications on the device. See Storing, Retrieving, and Exposing Data

to learn how to store and retrieve private data, how to store and retrieve common data from the device, and how to expose

your private data to other applications.

Please see the document Android Media APIs for more details.

You can create a listening class that can be notified or even instantiated whenever a specific type of system message is

sent.

The listening classes, called intent receivers, extend IntentReceiver. If you want Android to instantiate the object whenever

an appropriate intent notification is sent, define the receiver with a <receiver> element in the AndroidManifext.xml file. If

the caller is expected to instantiate the object in preparation to receive a message, this is not required. The receiver will get a

call to their IntentReceiver.onReceiveIntent() method. A receiver can define an <intent-filter> tag that describes the

types of messages it will receive. Just as Android's IntentResolver will look for appropriate Activity matches for a

startActivity() call, it will look for any matching Receivers (but it will send the message to all matching receiver, not the "best"

match).

To send a notification, the caller creates an Intent object and calls Activity.broadcastIntent() with that Intent. Multiple

recipients can receive the same message. You can broadcast an Intent message to an intent receiver in any application, not

only your own. If the receiving class is not registered using <receiver> in its manifest, you can dynamically instantiate and

register a receiver by calling Context.registerReceiver() .

Receivers can include intent filters to specify what kinds of intents they are listening for. Alternatively, if you expect a single

known caller to contact a single known receiver, the receiver does not specify an intent filter, and the caller specifies the

receiver's class name in the Intent by calling Intent.setClassName() with the recipient's class name. The recipient receives a

Context object that refers to its own package, not to the package of the sender.

Note: If a receiver or broadcaster enforces permissions, your application might need to request permission to send or

receive messages from that object. You can request permission by using the <uses-permission> tag in the manifest.

Here is a code snippet of a sender and receiver. This example does not demonstrate registering receivers dynamically. For

a full code example, see the AlarmService class in the ApiDemos project.

// We are sending this to a specific recipient, so we will

// only specify the recipient class name.

Intent intent = new Intent(this, AlarmReceiver.class);

intent.putExtra("message","Wake up.");

broadcastIntent(intent);

Receiver AndroidManifest.xml (because there is no intent filter child, this class will only receive a broadcast when the

receiver class is specified by name, as is done in this example):

<receiver class=".AlarmReceiver" />

Storing and Retrieving Larger or More Complex Persistent Data

Playing Media Files

Listening For and Broadcasting Global Messages, and Setting Alarms

Sending the message

Receiving the message

40Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 42: Documentation Android

Receiver Java code:

public class AlarmReceiver extends IntentReceiver{

// Display an alert that we've received a message.

@Override

public void onReceiveIntent(Context context, Intent intent){

// Send a text notification to the screen.

NotificationManager nm = (NotificationManager)

context.getSystemService(Context.NOTIFICATION_SERVICE);

nm.notifyWithText(R.id.alarm,

"Alarm!!!",

NotificationManager.LENGTH_SHORT,

null);

}

}

You can listen for other system messages sent by Android as well, such as USB connection/removal messages, SMS arrival

messages, and timezone changes. See Intent for a list of broadcast messages to listen for. Messages are marked

"Broadcast Action" in the documentation.

The telephony package overview page describes how to register to listen for phone events.

Android provides an AlarmManager service that will let you specify an Intent to send at a designated time. This intent is

typically used to start an application at a preset time. (Note: If you want to send a notification to a sleeping or running

application, use Handler instead.)

There are two major kinds of alerts that you may display to the user: (1) Normal alerts are displayed in response to a user

action, such as trying to perform an action that is not allowed. (2) Out-of-band alerts, called notifications, are displayed as a

result of something happening in the background, such as the user receiving new e-mail.

Android provides a number of ways for you to show popup notifications to your user as they interact with your application.

Class Description

app.Dialog A generic floating dialog box with a layout that you design.

app.AlertDialog

or

Context.showAlert()

A popup alert dialog with two buttons (typically OK and Cancel) that take callback handlers. It

can be created separately, or launched using the Application helper method

Context.showAlert(). See the section after this table for more details.

ProgressDialog A dialog box used to indicate progress of an operation with a known progress value or an

indeterminate length (setProgress(bool)). See Views > Progress Bar in ApiDemos for

examples.

Activity By setting the theme of an activity to android:theme="android:style/Theme.Dialog" , your activity

will take on the appearance of a normal dialog, floating on top of whatever was underneath it.

You usually set the theme through the android:theme attribute in your AndroidManifest.xml. The

advantage of this over Dialog and AlertDialog is that Application has a much better managed

Other system messages

Listening for phone events

Setting Alarms

Displaying Alerts

Normal Alerts

41Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 43: Documentation Android

This is a basic warning dialog box that lets you configure a message, button text, and callback. You can create one by calling

the Application helper method Context.showAlert(), as shown here.

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

switch (msg.what) {

case ACCEPT_CALL:

answer(msg.obj);

break;

case BOUNCE_TO_VOICEMAIL:

voicemail(msg.obj);

break;

}

}

};

private void IncomingMotherInlawCall(Connection c) {

String Text;

// "Answer" callback.

Message acceptMsg = Message.obtain();

acceptMsg.target = mHandler;

acceptMsg.what = ACCEPT_CALL;

acceptMsg.obj = c.getCall();

// "Cancel" callback.

Message rejectMsg = Message.obtain();

rejectMsg.target = mHandler;

rejectMsg.what = BOUNCE_TO_VOICEMAIL;

rejectMsg.obj = c.getCall();

showAlert(null, "Phyllis is calling", "Answer", acceptMsg, true, rejectMsg);

}

Out-of-band alerts should always be displayed using the NotificationManager, which allows you to tell the user about

something they may be interested in without disrupting what they are currently doing. A notification can be anything from a

brief pop-up box informing the user of the new information, through displaying a persistent icon in the status bar, to vibrating,

playing sounds, or flashing lights to get the user's attention. In all cases, the user must explicitly shift their focus to the

notification before they can interact with it.

The following code demonstrates using NotificationManager to display a basic text popup when a new SMS message arrives

in a listening service, and provides the current message count. You can see several more examples in the ApiDemos

application, under app/ (named notification*.java).

static void setNewMessageIndicator(Context context, int messageCount){

// Get the static global NotificationManager object.

NotificationManager nm = NotificationManager.getDefault();

// If we're being called because a new message has been received,

// then display an icon and a count. Otherwise, delete the persistent

// message.

AlertDialog

Notifications

42Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 44: Documentation Android

if (messageCount > 0) {

nm.notifyWithText(myApp.NOTIFICATION_GUID, // ID for this notification.

messageCount + " new message" + messageCount > 1 ? "s":"", // Text to

display.

NotificationManager.LENGTH_SHORT); // Show it for a short time only.

}

}

To display a notification in the status bar and have it launch an intent when the user selects it (such as the new text message

notification does), call NotificationManager.notify(), and pass in vibration patterns, status bar icons, or Intents to associate

with the notification.

An activity can display a progress bar to notify the user that something is happening. To display a progress bar in a screen,

call Activity.requestWindowFeature(Window.FEATURE_PROGRESS) . To set the value of the progress bar, call

Activity.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, level). Progress bar values are from 0 to 9,999, or set

the value to 10,000 to make the progress bar invisible.

You can also use the ProgressDialog class, which enables a dialog box with an embedded progress bar to send a "I'm

working on it" notification to the user.

You can't. Only a user can add an application to the Favorites list.

Every Android screen has a default menu with default options, such as adding the activity to the favorites menu. You can

add your own menu entries to the default menu options by implementing Activity.onCreateOptionsMenu or

Activity.onPrepareOptionsMenu(), and adding Item objects to the Menu passed in. To handle clicks implement

Activity.onOptionsItemSelected() to handle the click in your Activity class. You may also pass the Item object a handler class

that implements the Runnable class (a handler) but this is less efficient and discouraged.

An application receives a callback at startup time to enable it to populate its menu. Additionally, it receives callbacks each

time the user displays the options menu to let you perform some contextual modifications on the menu. To populate the

menu on startup, override Activity.onCreateOptionsMenu; to populate it when the menu is called (somewhat less efficient),

you can override Activity.onPrepareOptionsMenu(). Each Activity has its own menu list.

Menu items are displayed in the order added, though you can group them as described in the Menu.add documentation. The

following code snippet adds three items to the default menu options and handles them through the overridden

Activity.onOptionsItemSelected() method. You can show or hide menu items by calling setItemShown() or setGroupShown().

// Called only the first time the options menu is displayed.

// Create the menu entries.

// Menu adds items in the order shown.

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

// Parameters for menu.add are:

// group -- Not used here.

// id -- Used only when you want to handle and identify the click yourself.

// title

menu.add(0, 0, "Zoom");

menu.add(0, 1, "Settings");

menu.add(0, 2, "Other");

Displaying a Progress Bar

Adding Your Application to the Favorites List

Adding Items to the Screen Menu

43Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 45: Documentation Android

return true;

}

// Activity callback that lets your handle the selection in the class.

// Return true to indicate that you've got it, false to indicate

// that it should be handled by a declared handler object for that

// item (handler objects are discouraged for reasons of efficiency).

@Override

public boolean onOptionsItemSelected(Menu.Item item){

switch (item.getId()) {

case 0:

showAlert("Menu Item Clicked", "Zoom", "ok", null, false, null);

return true;

case 1:

showAlert("Menu Item Clicked", "Settings", "ok", null, false, null);

return true;

case 2:

showAlert("Menu Item Clicked", "Other", "ok", null, false, null);

return true;

}

return false;

}

You can add key shortcuts by calling the Item.setAlphabeticShortcut() or Item.setNumericShortcut() methods, as

demonstrated here to add a "C" shortcut to a menu item:

thisItem.setAlphabeticShortcut(0, 'c');

Add a submenu by calling Menu.addSubMenu(), which returns a SubMenu object. You can then add additional items to this

menu. Menus can only be one level deep, and you can customize the appearance of the submenu menu item.

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

// Parameters for menu.add are:

// group -- Not used here.

// id -- Used only when you want to handle and identify the click yourself.

// title

menu.add(0, 0, "Send message");

menu.add(0, 1, "Settings");

menu.add(0, 2, "Local handler");

menu.add(0, 3, "Launch contact picker");

// Add our submenu.

SubMenu sub = menu.addSubMenu(1, 4, "Days of the week");

sub.add(0, 5, "Monday");

sub.add(0, 6, "Tuesday");

sub.add(0, 7, "Wednesday");

sub.add(0, 8, "Thursday");

sub.add(0, 9, "Friday");

sub.add(0, 10, "Saturday");

sub.add(0, 11, "Sunday");

return true;

}

You can also advertise your Activity's services so that other Activities can add your activity to their own option menu. For

Adding Submenus

Adding yourself to menus on other applications

44Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 46: Documentation Android

example, suppose you implement a new image handling tool that shrinks an image to a smaller size and you would like to

offer this as a menu option to any other Activity that handles pictures. To do this, you would exposes your capabilities inside

an intent filter in your manifest. If another application that handles photos asks Android for any Activities that can perform

actions on pictures, Android will perform intent resolution, find your Activity, and add it to the other Activity's options menu.

The application offering the service must include an <intent-filter> element in the manifest, inside the <activity>

tag of the offering Activity. The intent filter includes all the details describing what it can do, such as a <type> element that

describes the MIME type of data that it can handle, a custom <action> value that describes what your handling application

can do (this is so that when it receives the Intent on opening it knows what it is expected to do), and most important, include

a <category> filter with the value android.intent.category.ALTERNATIVE and/or

android.intent.category.SELECTED_ALTERNATIVE (SELECTED_ALTERNATIVE is used to handle only the

currently selected element on the screen, rather than the whole Activity intent.

Here's an example of a snip of a manifest that advertises picture shrinking technology for both selected items and the whole

screen.

<activity class="PictureShrink"> <!-- Handling class -->

<intent-filter label="Shrink picture"> <!-- Menu label to display -->

<action value="com.example.sampleapp.SHRINK_IT" />

<type value="image/*" /> <!-- MIME type for generic images -->

<category value="android.intent.category.ALTERNATIVE " />

<category value="android.intent.category.SELECTED_ALTERNATIVE" />

</intent-filter>

</activity>

An application that wants to display a menu that includes any additional external services must, first of all, handle its menu

creation callback. As part of that callback it creates an intent with the category Intent.ALTERNATIVE_CATEGORY and/or

Intent.SELECTED_ALTERNATIVE, the MIME type currently selected, and any other requirements, the same way as it would

satisfy an intent filter to open a new Activity. It then calls menu.addIntentOptions() to have Android search for and add any

services meeting those requirements. It can optionally add addit ional custom menu items of its own.

You should implement SELECTED_ALTERNATIVE in onPrepareOptionsMenu() rather than onCreateOptionsMenu(),

because the user's selection can change after the application is launched.

Here's a code snippet demonstrating how a picture application would search for additional services to display on its menu.

@Override public boolean

onCreateOptionsMenu(Menu menu){

super.onCreateOptionsMenu(menu);

// Create an Intent that describes the requirements to fulfill to be included

// in our menu. The offering app must include a category value of

Intent.ALTERNATIVE_CATEGORY.

Intent intent = new Intent(null, getIntent().getData());

intent.addCategory(Intent.ALTERNATIVE_CATEGORY);

// Search for, and populate the menu with, acceptable offering applications.

menu.addIntentOptions(

0, // Group

0, // Any unique IDs we might care to add.

MySampleClass.class.getName(), // Name of the class displaying the menu--here,

its this class.

null, // No specifics.

intent, // Previously created intent that describes our requirements.

0, // No flags.

null); // No specifics.

return true;

The offering application

The menu-displaying application

}

45Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 47: Documentation Android

Use the webkit.WebView object.

You can bind a ListView to a set of underlying data by using a shim class called ListAdapter (or a subclass). ListAdapter

subclasses bind to a variety of data sources, and expose a common set of methods such as getItem() and getView(), and

uses them to pick View items to display in its list. You can extend ListAdapter and override getView() to create your own

custom list items. There are essentially only two steps you need to perform to bind to data:

Create a ListAdapter object and specify its data source1.

Give the ListAdapter to your ListView object.2.

That's it!

Here's an example of binding a ListActivity screen to the results from a cursor query. (Note that the setListAdapter() method

shown is a convenience method that gets the page's ListView object and calls setAdapter() on it.)

// Run a query and get a Cursor pointing to the results.

Cursor c = People.query(this.getContentResolver(), null);

startManagingCursor(c);

// Create the ListAdapter. A SimpleCursorAdapter lets you specify two interesting

things:

// an XML template for your list item, and

// The column to map to a specific item, by ID, in your template.

ListAdapter adapter = new SimpleCursorAdapter(this,

android.R.layout.simple_list_item_1, // Use a template that displays a

text view

c, // Give the cursor to the list

adapter

new String[] {People.NAME} , // Map the NAME column in the

people database to...

new String[] {"text1"}); // The "text1" view defined in the

XML template

setListAdapter(adapter);

See view/List4 in the ApiDemos project for an example of extending ListAdapter for a new data type.

You can hook into the device's camera onto your own Canvas object by using the CameraDevice class. See that class's

documentation, and the ApiDemos project's Camera Preview applicat ion (Graphics/Camera Preview) for example code.

Avoid performing long-running operations (such as network I/O) direct ly in the UI thread — the main thread of an application

where the UI is run — or your application may be blocked and become unresponsive. Here is a brief summary of the

recommended approach for handling expensive operations:

Create a Handler object in your UI thread1.

Spawn off worker threads to perform any required expensive operations2.

Display a Web Page

Binding to Data

Capture Images from the Phone Camera

Handling Expensive Operations in the UI Thread

Post results from a worker thread back to the UI thread's handler either through a Runnable or a Message3.

Update the views on the UI thread as needed4.

46Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 48: Documentation Android

The following outline illustrates a typical implementation:

public class MyActivity extends Activity {

[ . . . ]

// Need handler for callbacks to the UI thread

final Handler mHandler = new Handler();

// Create runnable for posting

final Runnable mUpdateResults = new Runnable() {

public void run() {

updateResultsInUi();

}

};

@Override

protected void onCreate(Bundle icicle) {

super.onCreate(icicle);

[ . . . ]

}

protected void startLongRunningOperation() {

// Fire off a thread to do some work that we shouldn't do directly in the UI

thread

Thread t = new Thread() {

public void run() {

mResults = doSomethingExpensive();

mHandler.post(mUpdateResults);

}

};

t.start();

}

private void updateResultsInUi() {

// Back in the UI thread -- update our UI elements based on the data in mResults

[ . . . ]

}

}

For further discussions on this topic, see Developing Responsive Applications and the Handler documentation.

You can highlight or style the formatting of strings or substrings of text in a TextView object. There are two ways to do this:

If you use a string resource, you can add some simple styling, such as bold or italic using HTML notation. So, for

example, in res/values/strings.xml you could declare this:<resource>

<string>id="@+id/styled_welcome_message">We are <b><i>so</i></b> glad to see

you.</string>

</resources>

To style text on the fly, or to add highlighting or more complex styling, you must use the Spannable object as described

next.

To style text on the fly, you must make sure the TextView is using Spannable storage for the text (this will always be true if

the TextView is an EditText), retrieve its text with getText(), and call setSpan(Object, int, int, int), passing in a new style class

Selecting, Highlighting, or Styling Portions of Text

47Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 49: Documentation Android

from the android.text.style package and the selection range.

The following code snippet demonstrates creating a string with a highlighted section, italic section, and bold section, and

adding it to an EditText object.

// Get our EditText object.

EditText vw = (EditText)findViewById(R.id.text);

// Set the EditText's text.

vw.setText("Italic, highlighted, bold.");

// If this were just a TextView, we could do:

// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);

// to force it to use Spannable storage so styles can be attached.

// Or we could specify that in the XML.

// Get the EditText's internal text storage

Spannable str = vw.getText();

// Create our span sections, and assign a format to each.

str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7,

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19,

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1,

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

The following list describes the structure and files of an Android application. Many of these files can be built for you (or

stubbed out) by the activityCreator.py application shipped in the tools/ menu of the SDK. See Building an Android Sample

Application for more information on using activityCreator.py.

MyApp/

AndroidManifest.xml (required) Advertises the screens that this application provides, where they

can be launched (from the main program menu or elsewhere), any content

providers it implements and what kind of data they handle, where the

implementation classes are, and other application-wide informat ion. Syntax

details for this file are described in AndroidManifest.xml.

src/

/myPackagePath/.../MyClass.java

(required) This folder holds all the source code files for your application,

inside the appropriate package subfolders.

res/ (required) This folder holds all the resources for your application. Resources

are external data files or description files that are compiled into your code at

build time. Files in different folders are compiled differently, so you must put

the proper resource into the proper folder. (See Resources for details.)

anim/

animation1.xml

...

(optional) Holds any animation XML description files that the application uses.

The format of these files is described in Resources.

drawable/

some_picture.png

some_stretchable.9.png

some_background .xml

...

(optional) Zero or more files that will be compiled to

android.graphics.drawable resources. Files can be image files (png, gif, or

other) or XML files describing other graphics such as bitmaps, stretchable

bitmaps, or gradients. Supported bitmap file formats are PNG (preferred),

JPG, and GIF (discouraged), as well as the custom 9-patch stretchable

bitmap format. These formats are described in Resources.

List of Files for an Android Application

48Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 50: Documentation Android

In most cases, every Android application runs in its own Linux process. This process is created for the application when

some of its code needs to be run, and will remain running until it is no longer needed and the system needs to reclaim its

memory for use by other applications.

An important and unusual feature of Android is that an application process's lifetime is not directly controlled by the

application itself. Instead, it is determined by the system through a combination of the parts of the application that the system

knows are running, how important these things are to the user, and how much overall memory is available in the system.

It is important that application developers understand how different application components (in particular Activity, Service,

and IntentReceiver) impact the lifetime of the application's process. Not using these components correctly can result in

the system killing the application's process while it is doing important work.

A common example of a process lifecycle bug is an IntentReceiver that starts a thread when it receives an Intent in its

onReceiveIntent() method, and then returns from the function. Once it returns, the system considers that IntentReceiver to

be no longer active, and thus its hosting process no longer needed (unless other application components are active in it).

Thus, it may kill the process at any time to reclaim memory, terminating the spawned thread that is running in it. The solution

to this problem is to start a Service from the IntentReceiver, so the system knows that there is still active work being done in

the process.

To determine which processes should be killed when low on memory, Android places them into an "importance hierarchy"

based on the components running in them and the state of those components. These are, in order of importance:

A foreground process is one holding an Activity at the top of the screen that the user is interacting with (its

onResume() method has been called) or an IntentReceiver that is currently running (its onReceiveIntent() method is

executing). There will only ever be a few such processes in the system, and these will only be killed as a last resort if

memory is so low that not even these processes can continue to run. Generally at this point the device has reached a

memory paging state, so this action is required in order to keep the user interface responsive.

1.

A visible process is one holding an Activity that is visible to the user on-screen but not in the foreground (its

onPause() method has been called). This may occur, for example, if the foreground activity has been displayed with a

dialog appearance that allows the previous activity to be seen behind it. Such a process is considered extremely

important and will not be killed unless doing so is required to keep all foreground processes running.

2.

A service process is one holding a Service that has been started with the startService() method. Though these

processes are not directly visible to the user, they are generally doing things that the user cares about (such as

background mp3 playback or background network data upload or down load), so the system will always keep such

processes running unless there is not enough memory to retain all foreground and visible process.

3.

A background process is one holding an Activity that is not currently visible to the user (its onStop() method has been

called). These processes have no direct impact on the user experience. Provided they implement their activity lifecycle

correctly (see Activity for more details), the system can kill such processes at any time to reclaim memory for one of

the three previous processes types. Usually there are many of these processes running, so they are kept in an LRU list

to ensure the process that was most recently seen by the user is the last to be killed when running low on memory.

4.

An empty process is one that doesn't hold any active application components. The only reason to keep such a

process around is as a cache to improve startup time the next time a component of its application needs to run. As

such, the system will often kill these processes in order to balance overall system resources between these empty

cached processes and the underlying kernel caches.

5.

When deciding how to classify a process, the system picks the most important level of all the components currently active in

the process. See the Activity, Service, and IntentReceiver documentation for more detail on how each of these components

contribute to the overall lifecycle of a process. The documentation for each of these classes describes in more detail how

they impact the overall lifecycle of their application.

Lifecycle of an Android Application

49Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 51: Documentation Android

The Android SDK includes a variety of custom tools that help you develop mobile applications on the

Android platform. The most important of these are the Android Emulator and the Android Development

Tools plugin for Eclipse, but the SDK also includes a variety of other tools for debugging, packaging,

and installing your applications on the emulator.

Android Emulator

A virtual mobile device that runs on your computer. You use the emulator to design, debug, and test

your applications in an actual Android run-time environment.

Android Development Tools Plugin for the Eclipse IDE

The ADT plugin adds powerful extensions to the Eclipse integrated environment, making creating and debugging your

Android applications easier and faster. If you use Eclipse, the ADT plugin gives you an incredible boost in developing

Android applications:

It gives you access to other Android development tools from inside the Eclipse IDE. For example, ADT lets you

access the many capabilities of the DDMS tool — taking screenshots, managing port-forwarding, setting

breakpoints, and viewing thread and process information — directly from Eclipse.

It provides a New Project Wizard, which helps you quickly create and set up all of the basic files you'll need for a

new Android application.

It automates and simplifies the process of building your Android application.

It provides an Android code editor that helps you write valid XML for your Android manifest and resource files.

For more information about the ADT plugin, including instal lation instructions, see Installing the ADT Plugin for Eclipse.

For a usage example with screenshots, see Hello Android.

Dalvik Debug Monitor Service (ddms)

Integrated with Dalvik, the Android platform's custom VM, this tool lets you manage processes on an emulator or device

and assists in debugging. You can use it to kill processes, select a specific process to debug, generate trace data, view

heap and thread information, take screenshots of the emulator or device, and more.

Android Debug Bridge (adb)

The adb tool lets you install your application's .apk files on an emulator or device and access the emulator or device

from a command line. You can also use it to link a standard debugger to application code running on an Android

emulator or device.

Android Asset Packaging Tool (aapt)

The aapt tool lets you create .apk files containing the binaries and resources of Android applications.

Android Interface Description Language (aidl)

Lets you generate code for an interprocess interface, such as what a service might use.

sqlite3

Included as a convenience, this tool lets you access the SQLite data files created and used by Android applications.

Traceview

This tool produces graphical analysis views of trace log data that you can generate from your Android application.

mksdcard

Helps you create a disk image that you can use with the emulator, to simulate the presence of an external storage card

(such as an SD card).

dx

The dx tool rewrites .class bytecode into Android bytecode (stored in .dex files.)

activityCreator

Development Tools

A script that generates Ant build files that you can use to compile your Android applicat ions. If you are developing on

Eclipse with the ADT plugin, you won't need to use this script.

50Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 52: Documentation Android

The Android SDK includes a mobile device emulator — a virtual device that

runs on your computer. The emulator lets you prototype, develop, and test

Android applications without using a physical device.

The Android emulator mimics all of the typical functions and behaviors of a

mobile device, except that it can not receive or place phone calls. As shown at

right, the emulator provides a variety of navigation and control keys, which you can "press" using your mouse or keyboard to generate events for your

application. It also provides a screen in which your application is displayed,

together with any other Android applications running.

To help you model and test your application, the emulator lets your application

use the services of the Android platform to invoke other applications, access

the network, play audio and video, store and retrieve data, notify the user, and

render graphical transitions and themes.

The emulator also includes a variety of debug capabilities, such as a console

from which you can log kernel output, simulate application interrupts (such as

arriving SMS messages or phone calls), and simulate latency effects and

dropouts on the data channel.

The sections below provide more information about the emulator and how to

use it when developing your applications.

Starting and Stopping the Emulator

Controlling the Emulator

Emulator Startup Options

Using the Emulator Console

Port Redirections

Network Status

Network Delay Emulation

Network Speed Emulation

Telephony Emulation

Using Emulator Skins

Running Multiple Instances of the Emulator

Installing Applications on the Emulator

SD Card Emulation

Creating a Disk Image

Copying Files to a Disk Image

Loading the Disk Image at Emulator Startup

Troubleshooting Emulator Problems

Android Emulator

Contents

Emulator Limitations

To start the emulator, change to the tools/ folder of the SDK and enter emulator or ./emulator. This initializes the

Android system and you will see the emulator window appear on your screen.

To stop the emulator, close the emulator window.

Starting and Stopping the Emulator

51Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 53: Documentation Android

You can use emulator startup options and console commands to control the behaviors and characteristics of the emulated

environment. Once the emulator is running, you can control it by using use your mouse pointer or keyboard keys to "press"

the simulated device keys.

The table below summarizes the mappings between the emulator keys and and the keys of your keyboard.

Emulator Key Keyboard Key

Back ESC

Menu F1 or PgUp

Star F2 or PgDn

Call F3

End Call F4

---- F5, F6 unassigned

Power button F7

Disable/enable all networking F8

Start tracing F9 (only with -trace flag)

Stop tracing F10 (only with -trace flag)

Home HOME

DPad left/up/right/down Keypad 4/8/6/2

DPad center click Keypad 5

Volume down Keypad minus sign (-)

Volume up Keypad plus sign (+)

The emulator supports a variety of options that you can specify when launching the emulator, to control its appearance or

behavior. Here's the command-line usage for launching the emula tor with options:

emulator [-option [value]] ... [-qemu args]

The table below summarizes the available options.

Controlling the Emulator

Emulator Startup Options

52Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 54: Documentation Android

Category Option Description Comments

Help -help Print a list of all emulator

commands.

Data -data [file] Use <file> as the working

user-data disk image.

If -data is not used, the emulator looks for

a file named "userdata.img" in ~/.android

(Linux/Mac) or C:\Documents and

Settings\<user>\Local Settings\Android

(Windows).

If you use -data <file> but <file> does

not exist, the emulator creates a file at that

location.

-ramdisk <file> Use <file> as the ramdisk

image.

Default value is <system>/ramdisk.img

-sdcard <file> Use <file> as the SD card

image.

Default value is <system>/sdcard.img

-wipe-data Wipe all data on the user disk

image (see -data) before

starting.

Debug -console Enable console shell on the

current terminal.

-debug-kernel Send kernel output to the

console.

-logcat

<logtags>

Enable logcat output with given

tags.

If the environment variable

ANDROID_LOG_TAGS is defined and not

empty, its value will be used to enable logcat

output by default

-trace <name> Enable code profiling (press F9

to start).

-verbose Enable verbose output.

-verbosekeys Enable verbose key presses.

Media -mic <device or

file>

Use device or WAV file for audio

input.

-noaudio Disable Android audio support. Set by default.

-radio <device> Redirect radio modem interface

to a host character device.

-useaudio Enable Android audio support. Disabled by default.

Network -netdelay

<delay>

Set network latency emulation to

<delay>.

Default value is none. See the table in

Network Delay Emulation for supported

53Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 55: Documentation Android

Each running emulator instance includes a console facility that lets you dynamically query and control the simulated device

environment. For example, you can use the console to dynamically manage port redirections and network characteristics

and simulate telephony events. To access the console and enter commands, you use telnet to connect to the console's port

number.

To connect to the console of any running emulator instance at any time, use this command:

telnet localhost <port>

The console of the first emulator instance running on a given machine uses port 5554. Subsequent instances use port

numbers increasing by two — for example, 5556, 5558, and so on. You can determine the port that an emulator instance is

using by starting it with the -verbose option and looking in the debug output for the line beginning, "emulator console

running on port number". Alternatively, you can use adb devices from the command line, to see a list of emulator

instances and their ports. Up to 16 concurrent instances can run a console facility.

Note: The emulator listens for connections on ports 5554-5587, from any computer. In a future release, the emulator will

accept connections only from localhost, but until then, you should use a firewall to block external connections to your

development machine on those ports.

Once the console is connected, you can then enter help [command] to see a list of console commands and learn about

specific commands.

To exit the console session, use quit or exit.

The sections below describe the major functional areas of the console.

You can use the console to add and remove port redirections while the emulator is running. After connecting to the console,

you can manage port redirections in this way:

redir <list|add|del>

The redir command supports the subcommands listed in the table below.

Subcommand Description Comments

list List the current port

redirections.

add <protocol>:<host-port>:<guest-port> Add a new port redirection. <protocol> must be either

"tcp" or "udp"

<host-port> is the port

number to open on the host

<guest-port> is the port

number to route data to on

the emulator/device

del <protocol>:<host-port> Delete a port redirection. See above for meanings of

<protocol> and <host-port>.

You can use the console to check the network status and current delay and speed characteristics. To do so, connect to the

Using the Emulator Console

Port Redirection

Network Status

console and use the netstatus command. Here's an example of the command and its output.

network status

54Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 56: Documentation Android

console and use the netstatus command. Here's an example of the command and its output.

network status

The emulator lets you simulate various network latency levels, so that you can test your applicaton in an environment more

typical of the actual conditions in which it will run. You can set a latency level or range at emulator startup or you can use the

console to change the latency dynamically, while the applicat ion is running in the emulator.

To set latency at emulator startup, use the -netdelay emulator option with a supported <delay> value, as listed in the

table below. Here are some examples:

emulator -netdelay gprs

emulator -netdelay 40 100

To make dynamic changes to network delay while the emulator is running, connect to the console and use the netdelay

command with a supported <delay> value from the table below.

network delay gprs

The format of network is one of the following (numbers are milliseconds):

Value Description Comments

gprs GPRS (min 150, max 550)

edge EDGE/EGPRS (min 80, max 400)

umts UMTS/3G (min 35, max 200)

none No latency (min 0, max 0)

<num> Emulate an exact latency

(milliseconds).

<min>:<max> Emulate an specified latency range

(min, max milliseconds).

The emulator also lets you simulate various network transfer rates. You can set a transfer rate or range at emulator startup

or you can use the console to change the rate dynamically, while the application is running in the emulator.

To set the network speed at emulator startup, use the -netspeed emulator option with a supported <speed> value, as

listed in the table below. Here are some examples:

emulator -netspeed gsm

emulator -netspeed 14.4 80

To make dynamic changes to network speed while the emulator is running, connect to the console and use the netspeed

command with a supported <speed> value from the table below.

network speed 14.4 80

The format of network <speed> is one of the following (numbers are kilobits/sec):

Network Delay Emulation

Network Speed Emulation

55Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 57: Documentation Android

Value Description Comments

gsm GSM/CSD (Up: 14.4, down: 14.4)

hscsd HSCSD (Up: 14.4, down: 43.2)

gprs GPRS (Up: 40.0, down: 80.0)

edge EDGE/EGPRS (Up: 118.4, down: 236.8)

umts UMTS/3G (Up: 128.0, down: 1920.0)

hsdpa HSDPA (Up: 348.0, down: 14400.0)

full no limit (Up: 0.0, down: 0.0)

<num> Set an exact rate used for both upload

and download.

<up>:<down> Set exact rates for upload and

download separately.

The Android emulator includes its own GSM emulated modem that lets you simulate telephony functions in the emulator. For

example, you can simulate inbound phone calls and establish/terminate data connections. The Android system handles

simulated calls exactly as it would actual calls. The emulator does not support call audio in this release.

You can use the console to access the emulator's telephony functions. After connecting to the console, you can use

gsm <call|data|voice>

to invoke telephony functions.

The gsm command supports the subcommands listed in the table below.

Subcommand Description Comments

call <phonenumber> Simulate an inbound

phone call from

<phonenumber>.

voice <state> Change the state of the

GPRS voice connection to

<state>.

Supported <state> values are:

unregistered -- No network available

home -- On local network, non-roaming

roaming -- On roaming network

searching -- Searching networks

denied -- Emergency calls only

off -- Same as 'unregistered'

on -- Same as 'home'

data <state> Change the state of the

GPRS data connection to

<state>.

Supported <state> values are:

unregistered -- No network available

home -- On local network, non-roaming

roaming -- On roaming network

searching -- Searching networks

Telephony Emulation

56Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 58: Documentation Android

You can run the emulator with any of four default skins, as described in the table below. To specify a skin, use -skin

<skinID> when starting the emulator.

For example:

emulator -skin HVGA-L

Note that you must enter the in uppercase letters (if your development computer is case-sensitive).

skinID Description Skin

QVGA-L 320x240, landscape (default)

QVGA-P 240x320, portrait

HVGA-L 480x320, landscape

HVGA-P 320x480, portrait

Using Emulator Skins

57Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 59: Documentation Android

You can run multiple instances of the emulator concurrently, if necessary. Each emulator instance uses separate user-data

memory and a different console port. This lets you manage each instance in isolation.

However, if you will run multiple emulator instances, note that there are limitations on the capability of each instance to

maintain its persistent user-data — user settings and installed applications — across sessions. Specifically:

Only the first emulator instance can preserve user data across sessions. It stores the user data in a file — by default, it

stores the data in the file ~/.android/userdata.img (on Linux and Mac) or C:\Documents and

Settings\<user>\Local Settings\Android\userdata.img (on Windows) in your development computer.

You can control the storage (and loading) location of the user data file by using the -data option when starting the

emulator (see Startup Options).

Emulator instances that you start after the first instance (that are running concurrently) also store user data during a

session, but they do not preserve it for the next session. These instances store the data in temporary files that are

deleted when their corresponding instances exit.

To install applications on the emulator, you use the adb utility.

Note that the emulator preserves user settings and installed applications across restarts. By default, the emulator saves the

user data in a file on your development computer. On Linux and Mac, the emulator stores the data in

~/.android/userdata.img. On Windows, the emulator stores the data in C:\Documents and Settings\. The

emulator uses the contents of the userdata.img file as the data/ folder.

You can create a disk image and then load it to the emulator at startup, to simulate the presence of a user's SD card in the

device. The sections below describe how to create the disk image, how to copy files to it, and how to load it in the emulator

at startup.

Note that you can only load disk image at emulator startup. Similarly, you can not remove a simulated SD card from a

running emulator. However, you can browse, send files to, and copy/remove files from a simulated SD card either with adb

or the emulator.

Also note that the emulator supports SD card images that are a maximum of 2 GB in size.

You can use the mksdcard tool, included in the SDK, to create a FAT32 disk image that you can load in the emulator at

startup. You can access mksdcard in the tools/ directory of the SDK and create a disk image like this:

mksdcard <size> <file>

For more information, see Other Tools.

Once you have created the disk image, you can copy files to it prior to loading it in the emulator. To copy files, you can

mount the image as a loop device and then copy the files to it, or you can use the mtools utility mcopy to copy the files

directly to the image. The mtools package is available for Linux, Mac, and Windows.

To load FAT32 disk image in the emulator, start the emulator with the -sdcard flag and specify the name and path of your

image (relative to the current working directory):

emulator -sdcard <filepath>

Running Multiple Emulator Instances

Installing Applications on the Emulator

SD Card Emulation

Creating a Disk Image

Copying Files to a Disk Image

Loading the Disk Image at Emulator Startup

58Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 60: Documentation Android

The adb utility sees the emulator as an actual physical device. For this reason, you might have to use the -d flag with some

common adb commands, such as install. The -d flag lets you specify which of several connected devices to use as the

target of a command. If you don't specify -d, the emulator will target the first device in its list. For more information about

adb, see Android Debug Bridge.

For emulators running on Mac OS X, if you see an error "Warning: No DNS servers found" when starting the emulator,

check to see whether you have an /etc/resolv.conf file. If not, please run the following line in a command window:

ln -s /private/var/run/resolv.conf /etc/resolv.conf

See Frequently Asked Questions for more troubleshooting information.

In this release, the limitations of the emulator include:

No support for placing or receiving actual phone calls. You can simulate phone calls (placed and received) through the

emulator console, however.

No support for USB connections

No support for camera/video capture (input).

No support for audio input (capture). Output (playback) is supported.

No support for device-attached headphones

No support for determining connected state

No support for determining battery charge level and AC charging state

No support for determining SD card insert/eject

No support for Bluetooth

Troubleshooting Emulator Problems

Emulator Limitations

59Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 61: Documentation Android

Android - An Open Handset Alliance Project

You can develop Android applications with the same high-quality tools you use to develop Java applications. The Android

core libraries provide the functionality needed to build some amazingly rich mobile applications, and the Android

development tools make running, debugging, and testing your applications a snap.

This section explains the ins and outs of developing Android applications. It outlines the philosophy behind the system and

then describes each of the key subsystems in detail. After reading this section, you'll have the knowledge and confidence to

begin writing that real-world Android app you have in mind.

Before reading this section you should read the Getting Started Guide, which helps you get up and running with the Android

SDK and shows you how to build a basic app. This section builds on the information in the Getting Started section.

Here's the content you'll find in this section:

Implementing a UI

Explains how to construct and interact with user interfaces for Android applications. After reading this page you'll have a

solid understanding of how Android layouts are built, how they operate at runtime, and how you can make them pretty.

Building Blocks

Detailed descriptions of Android components. Covers the ins and outs of the components summarized in Anatomy of an

Android App, plus more. This section goes into detail on each of the key Android components (Intents, Activities, Views,

and events.)

Storing and Retrieving Data

How to read and write data to the various storage mechanisms provided by Android, and to network services. There are

several different ways to read and write data from an Android application, each aimed at different needs. This page

describes them all and explains how to pick the right one for your needs.

Security Model

Gaining access to secure system resources and features, and declaring permissions to control access to your own

secure features. Permissions control whether a given application is able to access piece of functionality provided by

another application (for example, which applications can dial the phone). This page describes how permissions work

and how to request permissions as well as define your own.

Resources and i18n

Detailed descriptions of Android's application-resource management system, including how it's used for

internationalization and localization. "Resources" are applicat ion assets (such as images, localized strings, and XML

layouts) that need to be resolved at runtime. This page describes how Android resolves which resource to load from a

selection of them, as well as how to create and use resources.

Developing Android Applications

This section describes the basics of how to implement the user interface of an Android screen. It covers the basic elements

that make up a screen, how to define a screen in XML and load it in your code, and various other tasks you'll need to handle

for your user interface.

Hierarchy of Screen Elements

Common Layout Objects

Working with AdapterViews (Binding to Data)

Designing Your Screen in XML

Hooking into a Screen Element

Listening for UI Notifications

Applying a Theme to Your Application

UI Elements and Concepts Glossary

Implementing a User Interface

Topics

60Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 62: Documentation Android

The basic functional unit of an Android application is the activity--an object of the class android.app.Activity. An activity can

do many things, but by itself it does not have a presence on the screen. To give your activity a screen presence and design

its UI, you work with views and viewgroups -- basic units of user interface expression on the Android platform.

A view is an object of base class android.view.View. It's a data structure whose properties store the layout and content for a

specific rectangular area of the screen. A View object handles measuring and layout, drawing, focus change, scrolling, and

key/gestures for the screen area it represents.

The View class serves as a base class for widgets -- a set of fully implemented subclasses that draw interactive screen

elements. Widgets handle their own measuring and drawing, so you can use them to build your UI more quickly. The list of

widgets available includes Text, EditText, InputMethod, MovementMethod, Button, RadioButton, Checkbox, and ScrollView.

A viewgroup is an object of class android.view.Viewgroup. As its name indicates, a viewgroup is a special type of view object

whose function is to contain and manage a subordinate set of views and other viewgroups, Viewgroups let you add structure

to your UI and build up complex screen elements that can be addressed as a single entity.

The Viewgroup class serves as a base class for layouts -- a set of fully implemented subclasses that provide common types

of screen layout. The layouts give you a way to build a structure for a set of views.

On the Android platform, you define an Activity's UI using a tree of view and viewgroup nodes, as shown in the diagram

below. The tree can be as simple or complex as you need to make it, and you can build it up using Android's set of

predefined widgets and layouts or custom view types that you create yourself.

To attach the tree to the screen for rendering, your Activity calls its setContentView() method and passes a reference to the

root node object. Once the Android system has the reference to the root node object, it can work directly with the node to

invalidate, measure, and draw the tree. When your Activity becomes active and receives focus, the system notifies your

activity and requests the root node to measure and draw the tree. The root node then requests that its child nodes draw

themselves -- in turn, each viewgroup node in the tree is responsible for drawing its direct children.

As mentioned previously, each view group has the responsibility of measuring its available space, laying out its children, and

calling Draw() on each child to let it render itself. The children may request a size and location in the parent, but the parent

object has the final decision on where how big each child can be.

Hierarchy of Screen Elements

Views

Viewgroups

A Tree-Structured UI

61Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 63: Documentation Android

Every viewgroup class uses a nested class that extends ViewGroup.LayoutParams. This subclass contains property types

that define a child's size and position, in properties appropriate for that view group class.

Note that every LayoutParams subclass has its own syntax for setting values. Each child element must define

LayoutParams that are appropriate for its parent, although it may define different LayoutParams for its children.

All viewgroups include width and height. Many also include margins and borders. You can specify width and height exactly,

though you probably won't want to do this often. More often you will tell your view to size itself either to the dimensions of its

content, or to become as big as its containing object will allow.

LayoutParams: How a Child Specifies Its Position and Size

The following are the most common view groups you'll use in your applications. This gives some basicinformation about each type; for in-depth detail, see the linked reference page topic for each.

FrameLayout is the simplest layout object. It is intended as a blank reserved space on your screen that you

can later fill with a single object — for example, a picture that you'll swap out. All child elements are pinned to

the top left corner of the screen; you cannot specify a location for a child of a FrameLayout. Later children will

simply be drawn over earlier objects, partially or totally obscuring them (unless the newer object is

transparent).

Common Layout Objects

FrameLayout

A LinearLayout aligns all children in a single direction — vertically or horizontally, depending on what property

you set on the LinearLayout. All children are stacked one after the other, so a vertical list will only have one

child per row, no matter how wide they are, and a horizontal list will only be one row high (the height of the

tallest child, plus padding). LinearLayout respects margins between children, and also gravity (right, center, or

left alignment of a child).

LinearLayout

LinearLayout also supports assigning a weight to individual children. This value allows children to expand to

fill any remaining space on a screen. This prevents a list of small objects from being bunched to one end of a

large screen, allowing them to expand to fill the space. Children specify a weight value, and any remaining

space is assigned to children in the proportion of their declared weight. Default weight is zero. So, for

example, if there are three text boxes, and two of them declare a weight of 1, two of them will expand equally

to fill the remaining space, and the third will not grow any additional amount.

62Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 64: Documentation Android

The following two forms represent a LinearLayout with

a set of elements: a button, some labels, some text

boxes. Both have padding values to adjust the

padding nicely. The text boxes have their width set to

FILL_PARENT; other elements are set to

WRAP_CONTENT. The gravity, by default, is left. The

form on the left has weight values unset (0 by

default); the form on the right has the comments text

box weight set to 1. If the Name textbox had also been set to 1, the Name and Comments text boxes would

be the same height.

Tip: To create a proportionate size layout on the

screen, create a container object that is

fill_parent, assign the children heights or widths of

zero, and then assign relative weight values to

each child, depending on what proportion of the

screen each should take.

Within a horizontal LinearLayout, items are aligned by the position of their text base line (the first line of the

first list element — topmost or leftmost — is considered the reference line). This is so that people scanning

elements in a form shouldn't have to jump up and down to read element text in neighboring elements. This

can be turned off by setting android:baselineAligned="false" in the layout XML.

TableLayout positions its children into rows and columns. A TableLayout consists of a number of TableRow

objects, each defining a row (actually, you can have other children, which will be explained below).

TableLayout containers do not display border lines for their rows, columns, or cells. Each row has zero or

more cells; each cell can hold one View object. The table has as many columns as the row with the most

cells. A table can leave cells empty. Cells cannot span columns, as they can in HTML. The following image

shows a table layout, with the invisible cell borders displayed as dotted lines.

TableLayout

Columns can be hidden, can be marked to stretch to fill available screen space, or can be marked as

shrinkable to force the column to shrink until the table fits the screen. See the reference documentation for

this class for more details. 63Compiled by fastop 2007-2

http://fastoponandroid.googlepages.com

Page 65: Documentation Android

AbsoluteLayout enables children to specify exact x/y coordinates to display on the screen, where (0,0) is the

upper left corner, and values increase as you move down or to the right. Margins are not supported, and

overlapping elements are allowed (although not recommended). We generally recommend against using

AbsoluteLayout unless you have good reasons to use it, because it is fairly rigid and does not work well with

different device displays.

RelativeLayout lets children specify their position relative to each other (specified by ID), or to the parent. So

you can align two elements by right border, or make one below another, or centered in the screen. Elements

are rendered in the order given, so if the first element is centered in the screen, other elements aligning

themselves to that element will be aligned relative to screen center. If using XML to specify this layout (as

described later), a referenced element must be listed before you refer to it.

Here is an example relative layout with the visible and invisible elements outlined. The root screen layout

object is a RelativeLayout object.

AbsoluteLayout

RelativeLayout

This diagram shows the class names of the screen elements, followed by a list of the properties of each.

Some of these properties are supported directly by the element, and some are supported by its LayoutParams

member (subclass RelativeLayout for all the elements in this screen, because all elements are children of a

RelativeLayout parent object). The RelativeLayout parameters are width, height, below, alignTop, toLeft,

padding, and marginLeft. Note that some of these parameters support values relative to other children —

hence the name RelativeLayout. These include the toLeft, alignTop, and below properties, which indicate the

object to the left, top, and below respectively.

64Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 66: Documentation Android

These objects all hold child UI elements. Some provide visible UI, and others only handle child layout.

Class Description

AbsoluteLayout Enables you to specify the location of child objects relative to the parent in exact

measurements (for example, pixels).

FrameLayout Layout that acts as a view frame to display a single object.

Gallery A horizontal scrolling display of images, from a bound list.

GridView Displays a scrolling grid of m columns and n rows.

LinearLayout A layout that organizes its children into a single horizontal or vertical row. It creates a

scrollbar if the length of the window exceeds the length of the screen.

ListView Displays a scrolling single column list.

Summary of Important View Groups

As we mentioned, some view groups have UI. These objects typically subclass AdapterView. Examples include such as

Gallery (an image selection widget) and ListView (a list of views). These objects have two jobs in common:

Filling the layout with data

Handling user selections

This is typically done by binding the class to an Adapter that gets its data from somewhere — either a list that the code

supplies, or query results from the device's database.

// Get a Spinner and bind it to an ArrayAdapter that

// references a String array.

private String[] fruit = {"apples", "oranges", "lemons"}

Spinner s1 = (Spinner)findViewById(R.id.fruitlist);

s1.setAdapter(new ArrayAdapter<String>(this, R.layout.spinner_1, mStrings));

// Load a Spinner and bind it to a data query.

private String[] cols={android.provider.Contacts.PeopleColumns.NAME};

private Cursor cur = managedQuery(android.provider.Contacts.People.CONTENT_URI, cols,

null, null);

s2.setAdapter(new CursorAdapter(cur, this));

Working with AdapterViews (Binding to Data)

Filling the layout with data

This is done by setting the class's AdapterView.OnItemClickListener member to a listener and catching the selection changes.

Handling user selections

// Create a message handling object as an anonymous class.

private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {

public void onItemClick(AdapterView parent, View v, int position, long id)

{

// Display a messagebox.

showAlert("You've got an event", "Clicked me!", "ok", false);

}

};

// Now hook into our object and set its onItemClickListener member

// to our class handler object.

mHistoryView = (ListView)findViewById(R.id.history);

mHistoryView.setOnItemClickListener(mMessageClickedHandler);

65Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 67: Documentation Android

Because designing a screen in code can be cumbersome, Android supports an XML syntax to design screens. Android defines a large

number of custom elements, each representing a specific Android View subclass. You can design a screen the same way you create HTML

files, as a series of nested tags, saved in an XML file inside the application's res/layout/ directory. To learn what elements are exposed,

and the format of the XML file, see Layout Resources. Each file describes a single android.view.View element, but this element can be either

a simple visual element, or a layout element that contains a collection of child objects (a screen or a portion of a screen). When Android

compiles your application, it compiles each file into an android.view.View resource that you can load in code by calling

setContentView(R.layout.layout_file_name) in your Activity.onCreate() implementation.

Each XML file is made of tags that correspond to Android GUI classes. These tags have attributes that roughly correspond to methods in that

class (for example, EditText has a text attribute that corresponds to EditText.setText).

Note that there is not an exact correspondence between class and method names, and element and attribute names — they're close, but not

always 1:1.

Also note that Android tends to draw elements in the order in which they appear in the XML. Therefore, if elements overlap, the last one in the

XML file will probably be drawn on top of any previously listed elements in that same space.

Each XML file is compiled into a tree rooted by single View or ViewGroup object, and so must contain a single root tag. In the following

example, it evaluates to the outermost LinearLayout object.

Attributes named layout_something apply to that object's LayoutParams member. Layout Resources also describes how to learn the

syntax for specifying LayoutParams properties.

The following values are supported for dimensions (described in TypedValue):

px (pixels)

dip (device independent pixels)

sp (scaled pixels — best for text size)

pt (points)

in (inches)

mm (millimeters)

Example: android:layout_width="25px"

For more information about these dimensions, see Dimension Values.

The following XML file creates the screen shown. Note that the text on the top of the screen was set by calling Activity.setTitle. Note that the

attributes that refer to relative elements (i.e., layout_toLeft) refer to the ID using the syntax of a relative resource (@id/ id_number).

<?xml version="1.0" encoding="utf-8"?>

<!-- Demonstrates using a relative layout to create a

form -->

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@drawable/blue"

android:padding="10px">

<TextView id="@+id/label"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Type here:"/>

<EditText id="@+id/entry"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@android:drawable/editbox_background"

Designing Your Screen in XML

66Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 68: Documentation Android

Loading the compiled layout resource is very easy, and done with a single call in the application's onCreate() method, as shown here:

protected void onCreate(Bundle savedValues)

{

// Be sure to call the super class.

super.onCreate(savedValues);

// Load the compiled layout resource into the window's

// default ViewGroup.

// The source file is res/layout/hello_activity.xml

setContentView(R.layout.hello_activity);

// Retrieve any important stored values.

restoreValues(savedValues);

}

Loading the XML Resource

You can get a handle to a screen element by calling Activity.findViewById. You can use this handle to set or retrieve any

values exposed by the object.

TextView msgTextView = (TextView)findViewById(R.id.msg);

msgTextView.setText(R.string.push_me);

Hooking into a Screen Element

Some UI notifications are automatically exposed and called by Android. For instance, Activity exposes overrideable methods

onKeyDown and onKeyUp, and Widget exposes onFocusChanged(boolean, int) . However, some important callbacks, such

as button clicks, are not exposed natively, and must be registered for manually, as shown here.

public class SendResult extends Activity

{

/**

* Initialization of the Screen after it is first created. Must at least

* call setContentView() to

* describe what is to be displayed in the screen.

*/

protected void onCreate(Bundle savedValues)

{

...

// Listen for button clicks.

Button button = (Button)findViewById(R.id.corky);

button.setOnClickListener(mCorkyListener);

}

// Create an anonymous class to act as a button click listener.

private OnClickListener mCorkyListener = new OnClickListener()

{

public void onClick(View v)

{

// To send a result, simply call setResult() before your

// activity is finished.

setResult(RESULT_OK, "Corky!");

finish();

}

};

Listening for UI Notifications

67Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 69: Documentation Android

If you do not explicitly specify a theme for your UI, Android will use the default theme defined by android.R.style.Theme.

Many times you will want to use a different system theme (such as Theme.Dark) or create your own theme (as described in

Style and Theme Resources).

To set your theme in XML, simply specify the desired theme in your AndroidManifest.xml file with the theme attribute. This

can be used with the <application> tag (shown here) to specify a default theme for all of your activities, and/or with the

<activity> to control the theme of a particular activity.

<!-- AndroidManifest.xml-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.google.android.home">

<application android:theme="@android:style/Theme.Dark" >

<activity class=".Home"

...

</activity>

</application>

</manifest>

You can also set the theme programmatically, if needed. When doing so, be sure to set the theme before creating any views

so that the correct theme is used for all of your user-interface elements. Note that this approach should typically be avoided,

especially from the main activities of your application, because the theme you set here may not be used for any animations

the system uses to show the activity (which is done before your application starts).

protected void onCreate(Bundle icicle) {

super.onCreate(icicle);

...

setTheme(android.R.style.Theme_Dark);

setContentView(R.layout.linear_layout_3);

}

Applying a Theme to your Application

Here is a list of common UI elements and concepts that you will see here and elsewhere in the SDK.

Activity

The standard screen in an Android application. Activity is a class that Android can start when a matching Intent is

thrown by this or another application. Most commonly, it is visibly represented by a full screen window that can receive

and handle UI events and perform complex tasks, because of the Window it uses to render its window. Though an

Activity is typically full screen, it can also be floating or transparent.

View

A rectangular area on the screen that can be drawn to, handles click, keystroke, and other interaction events. A View is

a base class for most components of an Activity or Dialog screen (text boxes, windows, and so on). It receives calls

from its container object to draw itself, and informs its parent object about where and how big it would like to be (which

may or may not be respected by the parent). It is represented by the base class View.

View Group

A container that holds multiple child View objects, deciding where they will be and how large they can be, and calling on

them to draw themselves when appropriate. Some are invisible and for layout only, while others have a UI themselves

(for instance, scrolling list boxes). View groups are all in the widget package, but extend ViewGroup.

UI Elements and Concepts Glossary

Widget

A form element, such as a text box or popup menu. They have the ability to draw themselves and handle UI events.

Widgets are all in the widget package.

Drawable

A visual element that is loaded into another UI element, typically as a background image. It does not receive events, but

does assign various other properties such as "state" and scheduling to enable subclasses such as animation objects or

image libraries. Many drawable objects are loaded from resource files — xml or bitmap files that describe the image.

The base class is Drawable. See Resources.

68Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 70: Documentation Android

Panel

A panel is a concept not backed by a specific class. It is a View of some sort that is tied in closely to a parent window,

but can handle clicks and perform simple functions related to its parent. A panel floats in front of its parent, and is

positioned relative to it. A common example of a panel (implemented by Android) is the options menu available to every

screen. At present, there are no specific classes or methods for creating a panel — it's more of a general idea.

Dialog

A dialog is a floating window that can have buttons, and acts as a lightweight form that is intended to, at most, perform a

simple action (such as click a button) and perhaps return a value. It is not intended to persist in the history stack,

contain complex layout, or perform complex actions. Android provides a default simple dialog for you with optional

buttons, though you can define a dialog layout yourself. The base class is Dialog, and the helper methods to open a

dialog box are the various Activity.showAlert() methods.

Window

An abstract class that specifies the elements of a generic window, such as the look and feel (title bar text, location and

content of menus, and so on). Dialog and Activity use an implementation of this class to render a window. You should

not need to implement this class.

Surface

A block of memory that gets composited to the screen. A Surface holds a Canvas object for drawing, and provides

various helper methods to draw layers and resize the surface. You should not use this class directly; use SurfaceView

instead.

SurfaceView

A View object that wraps a Surface for drawing, and exposes methods to specify its size and format dynamically. The

camera app uses SurfaceView for its preview screen. A SurfaceView provides a way to draw independently of the UI

thread for resource-intense operations (such as games or camera previews), but it uses extra memory as a result.

SurfaceView supports both Canvas and OpenGL ES graphics.

Canvas

A drawing surface where the actual bits are composited. It has methods for standard computer drawing of bitmaps,

lines, circles, rectangles, text, and so on. It is bound to a Bitmap or Surface. Canvas is the simplest, easiest way to draw

2D objects on the screen. However, it does not support hardware acceleration, as OpenGL ES does.

OpenGL ES

Android provides OpenGL ES libraries that you can use for fast, complex 3D images. It is much harder to use than a

Canvas object, but better for 3D objects. The graphics.glutils package exposes OpenGL ES functionality.

69Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 71: Documentation Android

You can think of an Android application as a collection of components, of various kinds. These components are for the most

part quite loosely coupled, to the degree where you can accurately describe them as a federation of components rather than

a single cohesive application.

Generally, these components all run in the same system process. It's possible (and quite common) to create multiple

threads within that process, and it's also possible to create completely separate child processes if you need to. Such cases

are pretty uncommon though, because Android tries very hard to make processes transparent to your code.

These are the most important parts of the Android APIs:

AndroidManifest.xml

The AndroidManifest.xml file is the control file that tells the system what to do with all the top-level components

(specifically activities, services, intent receivers, and content providers described below) you've created. For instance,

this is the "glue" that actually specifies which Intents your Activities receive.

Activities

An Activity is, fundamentally, an object that has a lifecycle. An Activity is a chunk of code that does some work; if

necessary, that work can include displaying a UI to the user. It doesn't have to, though - some Activities never display

UIs. Typically, you'll designate one of your application's Activities as the entry point to your application.

Views

A View is an object that knows how to draw itself to the screen. Android user interfaces are comprised of trees of Views.

If you want to perform some custom graphical technique (as you might if you're writing a game, or building some

unusual new user interface widget) then you'd create a View.

Intents

An Intent is a simple message object that represents an "intention" to do something. For example, if your application

wants to display a web page, it expresses its "Intent" to view the URI by creating an Intent instance and handing it off to

the system. The system locates some other piece of code (in this case, the Browser) that knows how to handle that

Intent, and runs it. Intents can also be used to broadcast interesting events (such as a notification) system-wide.

Services

A Service is a body of code that runs in the background. It can run in its own process, or in the context of another

application's process, depending on its needs. Other components "bind" to a Service and invoke methods on it via

remote procedure calls. An example of a Service is a media player; even when the user quits the media-selection UI,

she probably still intends for her music to keep playing. A Service keeps the music going even when the UI has

completed.

Notifications

A Notification is a small icon that appears in the status bar. Users can interact with this icon to receive information. The

most well-known notifications are SMS messages, call history, and voicemail, but applications can create their own.

Notifications are the strongly-preferred mechanism for alerting the user of something that needs their attention.

ContentProviders

A ContentProvider is a data storehouse that provides access to data on the device; the classic example is the

ContentProvider that's used to access the user's list of contacts. Your application can access data that other

applications have exposed via a ContentProvider, and you can also define your own ContentProviders to expose data of

your own.

Android Building Blocks

70Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 72: Documentation Android

AndroidManifest.xml is a required file for every application. It sits in the root folder for an application, and describes global

values for your package, including the application components (activities, services, etc) that the package exposes and the

implementation classes for each component, what kind of data each can handle, and where they can be launched.

An important aspect of this file are the intent filters that it includes. These filters describe where and when that activity can be

started. When an activity (or the operating system) wants to perform an action such as open a Web page or open a contact

picker screen, it creates an Intent object. This object can hold several descriptors describing what you want to do, what data

you want to do it to, the type of data, and other bits of information. Android compares the information in an Intent object with

the intent filter exposed by every application and finds the activity most appropriate to handle the data or action specified by

the caller. More details on intents is given in the Intent reference page.

Besides declaring your application's Activities, Content Providers, Services, and Intent Receivers, you can also specify

permissions and instrumentation (security control and testing) in AndroidManifest.xml. For a reference of the tags and their

attributes, please see AndroidManifest.

A simple AndroidManifest.xml looks like this:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.my_domain.app.helloactivity">

<application android:label="@string/app_name">

<activity class=".HelloActivity">

<intent-filter>

<action android:value="android.intent.action.MAIN"/>

<category android:value="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity>

</application>

</manifest>

Some general items to note:

Almost every AndroidManifest.xml (as well as many other Android XML files) will include the namespace declaration

xmlns:android="http://schemas.android.com/apk/res/android" in its first element. This makes a variety

of standard Android attributes available in the file, which will be used to supply most of the data for elements in that file.

Most manifests include a single <application> element, which defines all of the application-level components and

properties that are available in the package.

Any package that will be presented to the user as a top-level application available from the program launcher will need

to include at least one Activity component that supports the MAIN action and LAUNCHER category as shown here.

Here is a detailed outline of the structure of an AndroidManifest.xml file, describing all tags that are available.

<manifest>

The root node of the file, describing the complete contents of the package. Under it you can place:

<uses-permission>

The AndroidManifest.xml File

Requests a security permission that your package must be granted in order for it to operate correctly. See the

Security Model document for more information on permissions. A manifest can contain zero or more of these

elements.

71Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 73: Documentation Android

<permission>

Declares a security permission that can be used to restrict which applications can access components or features

in your (or another) package. See the Security Model document for more information on permissions. A manifest

can contain zero or more of these elements.

<instrumentation>

Declares the code of an instrumentation component that is available to test the functionality of this or another

package. See Instrumentation for more details. A manifest can contain zero or more of these elements.

<application>

Root element containing declarations of the application-level components contained in the package. This element

can also include global and/or default attributes for the application, such as a label, icon, theme, required

permission, etc. A manifest can contain zero or one of these elements (more than one application tag is not

allowed). Under it you can place zero or more of each of the following component declarations:

<activity>

An Activity is the primary facility for an application to interact with the user. The initial screen the user sees

when launching an application is an activity, and most other screens they use will be implemented as separate

activities declared with additional activity tags.

Note: Every Activity must have an <activity> tag in the manifest whether it is exposed to the world or intended

for use only within its own package. If an Activity has no matching tag in the manifest, you won't be able to

launch it.

Optionally, to support late runtime lookup of your activity, you can include one or more <intent-filter> elements

to describe the actions the activity supports:

<intent-filter>

Declares a specific set of Intent values that a component supports, in the form of an IntentFilter. In

addition to the various kinds of values that can be specified under this element, attributes can be given

here to supply a unique label, icon, and other information for the action being described.

<action>

An Intent action that the component supports.

<category>

An Intent category that the component supports.

<type>

An Intent data MIME type that the component supports.

<scheme>

An Intent data URI scheme that the component supports.

<authority>

An Intent data URI authority that the component supports.

<path>

An Intent data URI path that the component supports.

<receiver>

An IntentReceiver allows an application to be told about changes to data or actions that happen, even if it is

not currently running. As with the activity tag, you can optionally include one or more <intent-filter> elements

that the receiver supports; see the activity's <intent-filter> description for more information.

<service>

A Service is a component that can run in the background for an arbitrary amount of time. As with the activity

tag, you can optionally include one or more <intent-filter> elements that the receiver supports; see the activity's

<intent-filter> description for more information.

<provider>

A ContentProvider is a component that manages persistent data and publishes it for access by other

applications.

72Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 74: Documentation Android

A typical desktop operating system provides a common file system that any application can use to store and read files that

can be read by other applications (perhaps with some access control settings). Android uses a different system: on Android,

all application data (including files) are private to that application. However, Android also provides a standard way for an

application to expose its private data to other applications. This section describes the many ways that an application can

store and retrieve data, expose its data to other applications, and also how you can request data from other applications that

expose their data.

Android provides the following mechanisms for storing and retrieving data:

Preferences

A lightweight mechanism to store and retrieve key/value pairs of primitive data types. This is typically used to store

application preferences.

Files

You can store your files on the device or on a removable storage medium. By default, other applications cannot access

these files.

Databases

The Android APIs contain support for SQLite. Your application can create and use a private SQLite database. Each

database is private to the package that creates it.

Content Providers

A content provider is a optional component of an application that exposes read/write access to an application's private

data, subject to whatever restrictions it wants to impose. Content providers implement a standard request syntax for

data, and a standard access mechanism for the returned data. Android supplies a number of content providers for

standard data types, such as personal contacts.

Network

Don't forget that you can also use the network to store and retrieve data.

Storing, Retrieving and Exposing Data

You can store application preferences such as a default greeting or text font to be loaded whenever this application is

started. Call Context.getSharedPreferences() to read and write values. Assign a name to your set of preferences if

you want to share them with other components in the same package, or use Activity.getPreferences() with no name

to keep them private to the calling activity. You cannot share preferences across packages. Here is an example of setting

user preferences for silent keypress mode for a calculator.

public class Calc extends Activity {

public static final String PREFS_NAME = "MyPrefsFile";

...

@Override

protected void onCreate(Bundle state){

super.onCreate(state);

...

// Restore preferences

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

boolean silent = settings.getBoolean("silentMode", false);

setSilent(silent); }

@Override

protected void onStop(){

super.onStop();

// Save user preferences. We need an Editor object to

// make changes. All objects are from android.context.Context

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

SharedPreferences.Editor editor = settings.edit();

editor.putBoolean("silentMode", mSilentMode);

// Don't forget to commit your edits!!!

editor.commit(); }}

Using Application Preferences

73Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 75: Documentation Android

Android provides access to read or write streams to files local to an application. Call Context.openFileOutput() and

Context.openFileInput() with a local name and path to read and write files. Calling these methods with the same name and

path strings from another application will not work; you can only access local files.

If you have static files to package with your application at compile time, you can save your file in your project in

res/raw/<mydatafile>, and then get it with Resources.openRawResource (R.raw.mydatafile).

Using Files

Android supports a SQLite database system and exposes database management functions that let you store complex

collections of data wrapped into useful objects. For example, Android defines a Contact data type that consists of many

fields including string first and last names, string address and phone numbers, a bitmap image, and much other information

describing the person. To create a database, use Context.createDatabase() and Context.openDatabase(), and read and

write this data as appropriate. (Note that file data such as a bitmap is typically stored as a string file path value in the

database, with the location of the local file.)

Android ships with the sqlite3 database tool, which enables you to browse table contents, run SQL commands, and perform

other useful functions on SQLite databases. See Examine databases (sqlite3) to learn how to run this program.

All databases, SQLite and others, are stored on the device in /data/data/<package_name>/databases

Discussion of how many tables to create, what fields they contain, and how they are linked, is beyond the scope of this

document, but Android does not impose any limitations beyond the standard SQLite concepts. We do recommend including

an autoincrement value key field that can be used as a unique ID to quickly find a record. This is not required for private

data, but if you implement a content provider, you must include such a unique ID field. See the sample class

NotePadProvider.java in the NotePad sample project for an example of creating and populating a new database. Any

databases you create will be accessible by name to any other class in the application, but not outside the application.

Using SQLite Databases

If you want to make your data public, you can create (or call) a content provider. This is an object that can store and retrieve

data accessible by all applications. This is the only way to share data across packages; there is no common storage area

that all packages can share. Android ships with a number of content providers for common data types (audio, video, images,

personal contact information, and so on). You can see some of Android's native content providers in the provider package.

How a content provider actually stores its data under the covers is up to the implementation of the content provider, but all

content providers must implement a common convention to query for data, and a common convention to return results.

However, a content provider can implement custom helper functions to make data storage/retrieval simpler for the specific

data that it exposes.

This document covers two topics related to Content Providers:

Using a Content Provider

Creating a Content Provider

Accessing Content Providers

This section describes how to store and retrieve data using a content provider implemented by you or anyone else. Android

exposes a number of content providers for a wide range of data types, from music and image files to phone numbers. You

can see a list of content providers exposed through the convenience classes in the android.provider package.

Android's content providers are loosely linked to their clients. Each content provider exposes a unique string (a URI)

identifying the type of data that it will handle, and the client must use that string to store or retrieve data of that type. We'll

explain this more in Querying for Data.

This section describes the following activities:

Querying for Data

Making the query

What the query returns

Querying for files

Reading retrieved data

Using a Content Provider to Store and Retrieve Data

74Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 76: Documentation Android

Modifying Data

Adding a Record

Deleting a Record

Each contact provider exposes a unique public URI (wrapped by ContentURI) that is used by a client to

query/add/update/delete data on that content provider. This URI has two forms: one to indicate all values of that type (e.g.,

all personal contacts), and one form to indicate a specific record of that type (e.g., Joe Smith's contact information).

content://contacts/people/ is the URI that would return a list of all contact names on the device.

content://contacts/people/23 is the URI string that would return a single result row, the contact with ID = 23. .

An application sends a query to the device that specifies a general type of item (all phone numbers), or a specific item

(Bob's phone number), to retrieve. Android then returns a Cursor over a recordset of results, with a specific set of columns.

Let's look at a hypothetical query string and a result set (the results have been trimmed a bit for clarity):

query = content://contacts/people/

Results:

Querying for Data

_ID _COUNT NUMBER NUMBER_KEY LABEL NAME TYPE

13 4 (425) 555 6677 425 555 6677 California office Bully Pulpit Work

44 4 (212) 555-1234 212 555 1234 NY apartment Alan Vain Home

45 4 (212) 555-6657 212 555 6657 Downtown office Alan Vain Work

53 4 201.555.4433 201 555 4433 Love Nest Rex Cars Home

Note that the query string isn't a standard SQL query string, but instead a URI string that describes the type of data to return.

This URI consists of three parts: the string "content://"; a segment that describes what kind of data to retrieve; and finally an

optional ID of a specific item of the specified content type. Here are a few more example query strings:

content://media/images is the URI string that would return a list of all images on the device.

content://contacts/people/ is the URI that would return a list of all contact names on the device.

content://contacts/people/23 is the URI string that would return a single result row, the contact with ID = 23.

Although there is a general form, query URIs are somewhat arbitrary and confusing. Therefore, Android provides a list of

helper classes in the android.provider package that define these query strings so you should not need to know the actual

URI value for different data types. These helper classes define a string (actually, a wrapper class called ContentURI) called

CONTENT_URI for a specific data type. For instance, android.provider.contacts.People.CONTENT_URI defines the query

string used to search for people in Android's built-in people content provider.

Typically you will use the defined CONTENT_URI object to make a query. The only time you should need to examine or

modify this string is to add an ID value to the end of the URI to retrieve a specific record. So, for example, if you were looking

for record 23 in the people contacts, you might run a query as shown here:

// Get the base URI for contacts.

ContentURI myPerson = new

ContentURI(android.provider.Contacts.People.CONTENT_URI.toURI());

// Add the ID of the record I'm looking for (I'd have to know this somehow).

myPerson.addId(23);

// Query for this record.

Cursor cur = managedQuery(myPerson, null, null, null);

This query returns a cursor over a database query result set. What columns are returned, what they're called, and what they

are named are discussed next. For now, though, know that you can specify that only certain columns be returned, the sort

order, and a SQL WHERE clause.

75Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 77: Documentation Android

You should use the Activity.managedQuery() method to retrieve a managed cursor. A managed cursor handles all the

niceties such as unloading itself when the application pauses, and requerying itself when the application restarts. You can

ask Android to manage an unmanaged cursor for you by calling Activity.startManagingCursor().

Let's look at an example query to retrieve a list of contact names, phone numbers, and photos.

// An array specifying which columns to return.

// The provider exposes a list of column names it returns for a specific

// query, or you can get all columns and iterate through them.

string[] projection = new string[] {

android.provider.BaseColumns._ID,

android.provider.Contacts.PeopleColumns.NAME,

android.provider.Contacts.PhonesColumns.NUMBER,

android.provider.Contacts.PeopleColumns.PHOTO

};

// Best way to retrieve a query; returns a managed query.

Cursor managedCursor = managedQuery( android.provider.Contacts.Phones.CONTENT_URI,

projection, //Which columns to return.

null, // WHERE clause--we won't specify.

android.provider.Contacts.PeopleColumns.NAME + " ASC"); //

Order-by clause.

This query will retrieve all the phone numbers stored in the phone number contacts provider. It will retrieve the name,

number, and unique record ID for each contact. We can then scroll through the result set forward or backward, delete

records, add records, and modify records, as described in the next sections.

What the query returns

A query returns a set of zero or more database records. The column names, order, and type are specific to the content

provider, but every query includes a column called _id, which is the ID of the item in that row. If a query can return binary

data, such as a bitmap or audio file, it will have a column with any name that holds a content:// URI that you can use to get

this data (more information on how to get the file will be given later). Here is a tiresome example result set for the previous

query:

_id name number photo

44 Alan Vain 212 555 1234 content://images/media/123

13 Bully Pulpit 425 555 6677 content://images/media/128

53 Rex Cars 201 555 4433 content://images/media/332

This result set demonstrates what is returned when we specified a subset of columns to return. The optional subset list is

passed in the projection parameter of the query. A content manager should list which columns it supports either by

implementing a set of interfaces describing each column (see Contacts.People.Phones, which extends BaseColumns,

PhonesColumns, and PeopleColumns), or by listing the column names as constants. Note that you need to know the data

type of a column exposed by a content provider in order to be able to read it; the field reading method is specific to the data

type, and a column's data type is not exposed programmatically.

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward through the result set. You

can use this cursor to read, modify, or delete rows. Adding new rows requires a different object described later.

Note that by convention, every recordset includes a field named _id, which is the ID of a specific record, and a _count field,

which is a count of records in the current result set. These field names are defined by BaseColumns.

Querying for Files

The previous query result demonstrates how a file is returned in a data set. The file field is typically (but not required to be) a

string path to the file. However, the caller should never try to read and open the file directly (permissions problems for one

thing can make this fail). Instead, you should call ContentResolver.openInputStream() /

ContentResolver.openOutputStream() , or one of the helper functions from a content provider.

76Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 78: Documentation Android

Reading Retrieved Data

The Cursor object retrieved by the query provides access to a recordset of results. If you have queried for a specific record

by ID, this set will contain only one value; otherwise, it can contain multiple values. You can read data from specific fields in

the record, but you must know the data type of the field, because reading data requires a specialized method for each type

of data. (If you call the string reading method on most types of columns, Android will give you the String representation of the

data.) The Cursor lets you request the column name from the index, or the index number from the column name.

If you are reading binary data, such as an image file, you should call ContentResolver.openOutputStream() on the string

content:// URI stored in a column name.

The following snippet demonstrates reading the name and phone number from our phone number query:

private void getColumnData(Cursor cur){

if(!cur.first())

return;

String name;

String phoneNumber;

int nameColumn = cur.getColumnIndex(android.provider.Contacts.PeopleColumns.NAME);

int phoneColumn =

cur.getColumnIndex(android.provider.Contacts.PhonesColumns.NUMBER);

int pathColumn = cur.getColumnIndex(android.provider.Contacts.PeopleColumns.PHOTO);

String imagePath;

while (cur.next()) {

// Get the field values

name = cur.getString(nameColumn);

phoneNumber = cur.getString(phoneColumn);

imagePath = cur.getString(stringColumn);

InputStream is = getContentResolver().openInputStream(imagePath);

... read the file stream into something...

is.close()

// Do something with the values.

...

}

}

Note that the image field is actually a string path value. Some content provider convenience classes provide helper methods

to get specific field values such as files more easily.

Remember, whenever calling updating methods on the Cursor class, you must call commitUpdates() to send the changes to

the database.

To update an individual record, set the Cursor to the appropriate object, call the appropriate update... method, and then call

commitUpdates().

To batch update a group of records (for example, to change "NY" to "New York" in all contact fields), call the

ContentResolver.update() method with the columns and values to change.

Remember, whenever calling updating methods on the Cursor class, you must call commitUpdates() to send the changes to

the database.

Modifying Data

To add a new record, call ContentResolver.insert() with the URI of the type of item to add, and a Map of any values you want

to set immediately on the new record. This will return the full URI of the new record, including record number, which you can

then use to query and get a Cursor over the new record.

Remember, whenever calling updating methods on the Cursor class, you must call commitUpdates() to send the changes to

the database.

Adding a New Record

77Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 79: Documentation Android

To save a file, you can call ContentResolver().openOutputStream() with the URI as shown in the next snippet, or

android.provider.Media.Images.insertImage(), in the snippet after that.

// Save the name and description in a map. Key is the content provider's

// column name, value is the value to save in that record field.

HashMap<String, Object> values = new HashMap<String, Object>();

values.put(Media.Images.NAME, "road_trip_1");

values.put(Media.Images.DESCRIPTION, "Day 1, trip to Los Angeles");

// Add a new record without the bitmap, but with the values.

// It returns the URI of the new record.

ContentURI uri = getContentResolver().insert(Media.Images.CONTENT_URI, values);

// Now get a handle to the file for that record, and save the data into it.

// sourceBitmap is a Bitmap object representing the file to save to the database.

OutputStream outStream = getContentResolver.openOutputStream(uri);

sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);

outStream.close();

Or, using a convenience class:

android.provider.Media.Images.insertImage( getContentResolver(),

sourceBitmap,

"road_trip_1",

"Day 1, trip to Los Angeles");

To delete a single record, call ContentResolver.delete() with the URI of a specific row, or call Cursor.deleteRow().

To delete multiple rows, call ContentResolver.delete() with the URI of the type of record to delete (for example,

android.provider.Contacts.People.CONTENT_URI) and a SQL WHERE clause defining which rows to delete (Warning: be

sure to include a valid WHERE clause if deleting a general type using ContentResolver.delete(), or else you risk deleting

more records than you intended!).

Remember, whenever calling updating methods on the Cursor class, you must call commitUpdates() to send the changes to

the database.

Deleting a Record

Here is how to create your own content provider to act as a public source for reading and writing a new data type:

Extend ContentProvider.1.

Define a public static final ContentURI named CONTENT_URI. This is the string that represents the full

"content://" URI that your content provider handles. You must define a unique string for this value; the best solution is

to use the fully-qualified class name of your content provider (lowercase). So, for example: public static final ContentURI CONTENT_URI = ContentURI.create(

"content://com.google.codelab.rssprovider");

2.

Create your system for storing your data. Most content providers store their data using Android's file storage methods

and SQLite databases, but you can store your data any way you want, so long as you follow the calling and return

value conventions.

3.

Creating a Content Provider

Define the column names that you will return to your clients. If you are using an underlying database, these column

names are typically are identical to the SQL database column names they represent. You should also include an

integer column named _id to define a specific record number. If using the SQLite database, this should be type

INTEGER PRIMARY KEY AUTOINCREMENT. The AUTOINCREMENT descriptor is optional, but by default, SQLite

autoincrements an ID counter field to the next number above the largest existing number in the table. If you delete the

last row, the next row added will have the same ID as the deleted row. To avoid this by having SQLite increment to the

next largest value whether deleted or not, then assign your ID column the following type: INTEGER PRIMARY KEY

AUTOINCREMENT. (Note You should have a unique _id field whether or not you have another field (such as a URL)

that is also unique among all records.) Android provides the ContentProviderDatabaseHelper class to help you create

and manage versions of your database.

4.

78Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 80: Documentation Android

If you are exposing byte data, such as a bitmap file, the field that stores this data should actually be a string field with a

content:// URI for that specific file. This is the field that clients will call to retrieve this data. The content provider for that

content type (it can be the same content provider or another content provider — for example, if you're storing a photo

you would use the media content provider) should implement a field named _data for that record. The _data field lists

the exact file path on the device for that file. This field is not intended to be read by the client, but by the

ContentResolver. The client will call ContentResolver.openOutputStream() on the user-facing field holding the URI for

the item (for example, the column named photo might have a value content://media/images/4453). The

ContentResolver will request the _data field for that record, and because it has higher permissions than a client, it

should be able to access that file directly and return a read wrapper for that file to the client.

5.

Declare public static Strings that clients can use to specify which columns to return, or to specify field values from the

cursor. Carefully document the data type of each field. Remember that file fields, such as audio or bitmap fields, are

typically returned as string path values

6.

Return a Cursor object over a recordset in reply to a query. This means implementing the query(), update(), insert(),

and delete() methods. As a courtesy, you might want to call ContentResolver.notifyChange() to notify listeners about

updated information.

7.

Add a <provider> tag to AndroidManifest.xml, and use its authorities attribute to define the authority part of the 8.

content type it should handle. For example, if your content type is content://com.example.autos/auto to request a list of

all autos, then authorities would be com.example.autos. Set the multiprocess attribute to true if data does not need

to be synchronized between multiple running versions of the content provider.

If you are handling a new data type, you must define a new MIME type to return for your implementation of

android.ContentProvider.getType(url) . This type corresponds to the content:// URI submitted to getType(), which

will be one of the content types handled by the provider. The MIME type for each content type has two forms: one for a

specific record, and one for multiple records. Use the ContentURI methods to help determine what is being requested.

Here is the general format for each:

vnd.<yourcompanyname>.cursor.item/<contenttype> for a single row. For example: a request for train

record 122, using content://com.example.transportationprovider/trains/122, might return the

MIME type vnd.example.cursor.item/rail

vnd.<yourcompanyname>.cursor.dir/<contenttype> for multiple rows. So, for example, a request for all

train records, using content://com.example.transportationprovider/trains might return the MIME

type vnd.example.cursor.dir/rail.

9.

For an example of a private content provider implementation, see the NodePadProvider class in the notepad sample

application that ships with the SDK.

Here is a recap of the important parts of a content URI:

Standard required prefix. Never modified. A.

Authority part. For third-party applications, this should be a fully-qualified class to ensure uniqueness. This

corresponds to the value in the <provider> element's authorities attribute: <provider

class="TransportationProvider" authorities="com.example.transportationprovider" />

B.

The path that the content provider uses to determine what kind of data is being requested. This can be zero or more

segments: if the content provider exposes only one type of data (only trains, for example), this can be absent. If it

provides several types, including subtypes, this can be several elements long: e.g., "land/bus, land/train,

sea/ship, and sea/submarine" to give four possibilities.

C.

A specific record being requested, if any. This is the _id value of a specific record being requested. If all records of a

specific type are being requested, omit this and the trailing slash:

content://com.example.transportationprovider/trains

D.

In addition to all the on-device storage options, you can also store and retrieve data from the network (when available). To

do network operations, you'll want to use the following packages:

java.net.*

android.net.*

Network Accesses with Android

79Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 81: Documentation Android

Android is a multi-process system, where each application (and parts of the system) runs in its own process. Most security

between applications and the system is enforced at the process level through standard Linux facilities, such as user and

group IDs that are assigned to applications. Additional finer-grained security features are provided through a "permission"

mechanism that enforces restrictions on the specific operations that a particular process can perform.

User IDs and File Access

Using Permissions

Declaring and Enforcing Permissions

Enforcing Permissions in AndroidManifest.xml

Enforcing Permissions when Broadcasting Intents

Other Permission Enforcement

Each Android package (.apk) file installed on the device is given its own unique Linux user ID, creating a sandbox for it and

preventing it from touching other applications (or other applications from touching it). This user ID is assigned to it when the

application is installed on the device, and generally remains constant for the duration of its life on that device.

Because security enforcement happens at the process level, the code of any two packages can not normally run in the same

process, since they need to run as different Linux users. You can use the sharedUserId attribute in the

AndroidManifest.xml's manifest tag of each package to have them assigned the same user ID. By doing this, for

purposes of security the two packages are then treated as being the same application, with the same user ID and file

permissions. Note that in order to retain security, only two applications signed with the same signature (and requesting the

same sharedUserId) will be given the same user ID.

Any files created by an application will be assigned that application's user ID, and not normally accessible to other packages.

When creating a new file with getSharedPreferences(String, int), openFileOutput(String, int), or createDatabase(String, int,

int, SQLiteDatabase.CursorFactory), you can use the MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE

flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but

its global read and/or write permissions have been set appropriately so any other application can see it.

A basic Android application has no permissions associated with it, meaning it can not do anything that would adversely

impact the user experience or any data on the device. To make use of protected features of the device, you must include in

your AndroidManifest.xml one or more <uses-permission> tags declaring the permissions that your application

needs.

For example, an application that needs to monitor incoming SMS messages would specify:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.google.android.app.myapp" >

<uses-permission id="android.permission.RECEIVE_SMS" />

Security and Permissions in Android

Contents

User IDs and File Access

Using Permissions

</manifest>

80Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 82: Documentation Android

At application install time, permissions requested by the application are granted to it by the package installer, based on

checks with trusted authorities and interaction with the user. No checks with the user are done while an application is

running: it either was granted a particular permission when installed, and can use that feature as desired, or the permission

was not granted and any attempt to use the feature will fail without prompting the user.

Often times a permission failure will result in a SecurityException being thrown back to the application. However, this is not

guaranteed to occur everywhere. For example, the broadcastIntent(Intent) method checks permissions as data is being

delivered to each receiver, after the method call has returned, so you will not receive an exception if there are permission

failures. In almost all cases, however, a permission failure will be printed to the system log.

The permissions provided by the Android system can be found at Manifest.permission. Any application may also define and

enforce its own permissions, so this is not a comprehensive list of all possible permissions.

A particular permission may be enforced at a number of places during your program's operation:

At the time of a call into the system, to prevent an application from executing certain functions.

When starting an activity, to prevent applications from launching activities of other applications.

Both sending and receiving Intent broadcasts, to control who can receive your broadcast or who can send a broadcast

to you.

When accessing and operating on a content provider.

Binding or starting a service.

To enforce your own permissions, you must first declare them in your AndroidManifest.xml using one or more

<permission> tags.

For example, an application that wants to control who can start one of its activities could declare a permission for this

operation as follows:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.google.android.app.myapp" >

<permission id="com.google.android.app.myapp.permission.DEADLY_ACTIVITY"

android:label="@string/permlab_deadlyActivity"

android:description="@string/permdesc_deadlyActivity" />

</manifest>

Note that both a label and description should be supplied for the permission. These are string resources that can be

displayed to the user when they are viewing a list of permissions (android:label) or details on a single permission (

android:description). The label should be short, a few words describing the key piece of functionality the permission is

protecting. The description should be a couple sentences describing what the permission allows a holder to do. Our

convention for the description is two sentences, the first describing the permission, the second warning the user of what bad

things can happen if an application is granted the permission.

Here is an example of a label and description for the CALL_PHONE permission:

<string name="permlab_callPhone">Call Phone Numbers</string>

<string name="permdesc_callPhone">Allows application to call

phone numbers without your intervention. Bad applications may

cause unexpected calls on your phone bill.</string>

High-level permissions restricting access to entire components of the system or application can be applied through your

AndroidManifest.xml All that this requires is including an android:permission attribute on the desired component,

Declaring and Enforcing Permissions

Enforcing Permissions in AndroidManifest.xml

naming the permission that will be used to control access to it.

Activity permissions (applied to the <activity> tag) restrict who can start the associated activity. The permission is checked

during Context.startActivity() and Activity.startSubActivity(); if the caller does not have the required permission then

SecurityException is thrown from the call.

81Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 83: Documentation Android

Service permissions (applied to the <service> tag) restrict who can start or bind to the associated service. The permission is

checked during Context.startService(), Context.stopService() and Context.bindService(); if the caller does not have the

required permission then SecurityException is thrown from the call.

IntentReceiver permissions (applied to the <receiver> tag) restrict who can broadcast Intent objects to the associated

receiver. The permission is checked after Context.broadcastIntent() returns, as the system tries to deliver the submitted

Intent to the given receiver. As a result, a permission failure will not result in an exception being thrown back to the caller; it

will just not deliver the intent. In the same way, a permission can be supplied to Context.registerReceiver() to control who

can broadcast to a programmatically registered receiver. Going the other way, a permission can be supplied when calling

Context.broadcastIntent() to restrict which IntentReceiver objects are allowed to receive the broadcast (see below).

ContentProvider permissions (applied to the <provider> tag) restrict who can access the data in a ContentProvider. Unlike

the other components, there are two separate permission attributes you can set: android:readPermission restricts who can

read from the provider, and android:writePermission restricts who can write to it. Note that if a provider is protected with both

a read and write permission, holding only the write permission does not mean you can read from a provider. The

permissions are checked when you first retrieve a provider (if you don't have either permission, a SecurityException will be

thrown), and as you perform operations on the provider. Using ContentResolver.query() requires holding the read

permission; using ContentResolver.insert(), ContentResolver.update(), ContentResolver.delete(), or

Cursor.commitUpdates() requires the write permission. In all of these cases, not holding the required permission results in a

SecurityException being thrown from the call.

In addition to the permission enforcing who can send Intents to a registered IntentReceiver (as described above), you can

also specify an permission when broadcasting an Intent. By calling Context.broadcastIntent() with a permission string, you

require that a receiver's application must hold that permission in order to receive your Intent.

Note that both a receiver and a broadcaster can require a permission. When this happens, both permission checks must

pass for the Intent to be delivered to the associated target.

Arbitrarily fine-grained permissions can be enforced at any call into a service. This is accomplished with the

Context.checkCallingPermission() method. Call with a desired permission string and it will return an integer indicating

whether that permission has been granted to the current calling process. Note that this can only be used as you are

executing a call coming in from another process, usually through an IDL interface published from a service or in some other

way given to another process.

There are a number of other useful ways to check permissions. If you have the pid of another process, you can use the

Context method Context.checkPermission(String, int, int) to check a permission against that pid. If you have the package

name of another application, you can use the direct PackageManager method Context.checkPermission(String, String) to

find out whether that particular package has been granted a specific permission.

Enforcing Permissions when Broadcasting Intents

Other Permission Enforcement

82Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 84: Documentation Android

Resources are external files (that is, non-code files) that are used by your code and compiled into your

application at build time. Android supports a number of different kinds of resource files, including XML, PNG,

and JPEG files. The XML files have very different formats depending on what they describe. This document

describes what kinds of files are supported, and the syntax or format of each.

Resources are externalized from source code, and XML files are compiled into a binary, fast loading format

for efficiency reasons. Strings, likewise are compressed into a more efficient storage form. It is for these

reasons that we have these different resource types in the Android platform.

This document contains the following sections:

Resources

Creating Resources

Using Resources

Using Resources in Code

References to Resources

References to Theme Attributes

Using System Resources

Alternate Resources

Resource Reference

Terminology

Internationalization (I18N)

This is a fairly technically dense document, and together with the Resource Reference document, they cover a

lot of information about resources. It is not necessary to know this document by heart to use Android, but

rather to know that the information is here when you need it.

This topic includes a terminology list associated with resources, and a series of examples of using resources

in code. For a complete guide to the supported Android resource types, see Resources.

The Android resource system keeps track of all non-code assets associated with an application. You use the

Resources class to access your application's resources; the Resources instance associated with your

application can generally be found through Context.getResources().

An application's resources are compiled into the application binary at build time for you by the build system. To

use a resource, you must install it correctly in the source tree and build your application. As part of the build

process, symbols for each of the resources are generated that you can use in your source code -- this allows

the compiler to verify that your application code matches up with the resources you defined.

The rest of this section is organized as a tutorial on how to use resources in an application.

Resources and Internationalization

Resources

Android supports string, bitmap, and many other types of resource. The syntax and format of each, and where

they're stored, depends upon the type of object. In general, though, you create resources from three types of

files: XML files (everything but bitmaps and raw), bitmap files(for images) and Raw files (anything else, for

example sound files, etc.). In fact, there are two different types of XML file as well, those that get compiled

as-is into the package, and those that are used to generate resources by aapt. Here is a list of each resource

Creating Resources

83Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 85: Documentation Android

type, the format of the file, a description of the file, and details of any XML files.

You will create and store your resource files under the appropriate subdirectory under the res/ directory in

your project. Android has a resource compiler (aapt) that compiles resources according to which subfolder

they are in, and the format of the file. Here is a list of the file types for each resource. See the resource

reference for descriptions of each type of object, the syntax, and the format or syntax of the containing file.

Directory Resource Types

res/anim/ XML files that are compiled into frame by frame animation or tweened animation

objects

res/drawable/.png, .9.png, .jpg files that are compiled into the following Drawable resource

subtypes:

To get a resource of this type, use Resource.getDrawable(id)

bitmap files

9-patches (resizable bitmaps)

res/layout/ XML files that are compiled into screen layouts (or part of a screen). See layouts

res/values/XML files that can be compiled into many kinds of resource.

Note: unlike the other res/ folders, this one can hold any number of files that hold

descriptions of resources to create rather than the resources themselves. The

XML element types control where these resources are placed under the R class.

While the files can be named anything, these are the typical files in this folder (the

convention is to name the file after the type of elements defined within):

arrays.xml to define arrays

colors.xml to define color drawables and color string values. Use

Resources.getDrawable() and Resources.getColor(),

respectively, to get these resources.

dimens.xml to define dimension value. Use Resources.getDimension()

to get these resources.

strings.xml to define string values (use either Resources.getString or

preferably Resources.getText() to get these resources. getText() will

retain any rich text styling which is usually desirable for UI strings.

styles.xml to define style objects.

res/xml/ Arbitrary XML files that are compiled and can be read at run time by calling

Resources.getXML().

Resources are compiled into the final APK file. Android creates a wrapper class, called R, that you can use to

refer to these resources in your code. R contains subclasses named according to the path and file name of

the source file

Several resources allow you to define colors. Android accepts color values written in various web-style

formats -- a hexadecimal constant in any of the following forms: #RGB, #ARGB, #RRGGBB,

#AARRGGBB.

All color values support setting an alpha channel value, where the first two hexadecimal numbers specify

the transparency. Zero in the alpha channel means transparent. The default value is opaque.

Global Resource Notes

84Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 86: Documentation Android

This section describes how to use the resources you've created. It includes the following topics:

Using resources in code - How to call resources in your code to instantiate them.

Referring to resources from other resources - You can reference resources from other resources. This

lets you reuse common resource values inside resources.

Supporting Alternate Resources for Alternate Configurations - You can specify different resources to

load, depending on the language or display configuration of the host hardware.

At compile time, Android generates a class named R that contains resource identifiers to all the resources in

your program. This class contains several subclasses, one for each type of resource supported by Android,

and for which you provided a resource file. Each class contains one or more identifiers for the compiled

resources, that you use in your code to load the resource. Here is a small resource file that contains string,

layout (screens or parts of screens), and image resources.

Note: the R class is an auto-generated file and is not designed to be edited by hand. It will be automatically

re-created as needed when the resources are updated.

package com.google.android.samples;

public final class R {

public static final class string {

public static final int greeting=0x0204000e;

public static final int start_button_text=0x02040001;

public static final int submit_button_text=0x02040008;

public static final int main_screen_title=0x0204000a;

};

public static final class layout {

public static final int start_screen=0x02070000;

public static final int new_user_pane=0x02070001;

public static final int select_user_list=0x02070002;

};

public static final class drawable {

public static final int company_logo=0x02020005;

public static final int smiling_cat=0x02020006;

public static final int yellow_fade_background=0x02020007;

public static final int stretch_button_1=0x02020008;

};

};

Using Resources

Using resources in code is just a matter of knowing the full resource ID and what type of object your resource

has been compiled into. Here is the syntax for referring to a resource:

R.resource_type.resource_name

or

android.R.resource_type.resource_name

Using Resources in Code

Where resource_type is the R subclass that holds a specific type of resource. resource_name is the name

attribute for resources defined in XML files, or the file name (without the extension) for resources defined by

other file types. Each type of resource will be added to a specific R subclass, depending on the type of resource

it is; to learn which R subclass hosts your compiled resource type, consult the resource reference document.

Resources compiled by your own application can be referred to without a package name (simply as

R.resource_type.resource_name). Android contains a number of standard resources, such as screen

styles and button backgrounds. To refer to these in code, you must qualify them with android, as in

android.R.drawable.button_background . 85Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 87: Documentation Android

Where resource_type is the R subclass that holds a specific type of resource. resource_name is the name

attribute for resources defined in XML files, or the file name (without the extension) for resources defined by

other file types. Each type of resource will be added to a specific R subclass, depending on the type of resource

it is; to learn which R subclass hosts your compiled resource type, consult the resource reference document.

Resources compiled by your own application can be referred to without a package name (simply as

R.resource_type.resource_name). Android contains a number of standard resources, such as screen

styles and button backgrounds. To refer to these in code, you must qualify them with android, as in

android.R.drawable.button_background .

Here are some good and bad examples of using compiled resources in code:

// Load a background for the current screen from a drawable resource.

this.getWindow().setBackgroundDrawableResource (R.drawable.my_background_image);

// WRONG Sending a string resource reference into a

// method that expects a string.

this.getWindow().setTitle(R.string.main_title);

// RIGHT Need to get the title from the Resources wrapper.

this.getWindow().setTitle(Resources.getText(R.string.main_title));

// Load a custom layout for the current screen.

setContentView(R.layout.main_screen);

// Set a slide in animation for a ViewFlipper object.

mFlipper.setInAnimation(AnimationUtils.loadAnimation(this,

R.anim.hyperspace_in));

// Set the text on a TextView object.

TextView msgTextView = (TextView)findViewByID(R.id.msg);

msgTextView.setText(R.string.hello_message);

A value supplied in an attribute (or resource) can also be a reference to a resource. This is often used in layout

files to supply strings (so they can be localized) and images (which exist in another file), though a reference can

be any resource type including colors and integers.

For example, if we have color resources, we can write a layout file that sets the text color size to be the value

contained in one of those resources:

<?xml version="1.0" encoding="utf-8"?>

<EditText id="text"

xmlns:android="http://schemas.android.com/apk/res/android"

References to Resources

android:layout_width="fill_parent" android:layout_height="fill_parent"

android:textColor="@color/opaque_red" android:text="Hello, World!" />

Note here the use of the '@' prefix to introduce a resource reference -- the text following that is the name of a

resource in the form of @[package:]type/name . In this case we didn't need to specify the package

because we are referencing a resource in our own package. To reference a system resource, you would need

to write:

86Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 88: Documentation Android

<?xml version="1.0" encoding="utf-8"?>

<EditText id="text"

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent" android:layout_height="fill_parent"

android:textColor="@android:color/opaque_red" android:text="Hello, World!" />

As another example, you should always use resource references when supplying strings in a layout file so that

they can be localized:

<?xml version="1.0" encoding="utf-8"?>

<EditText id="text"

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent" android:layout_height="fill_parent"

android:textColor="@android:color/opaque_red"

android:text="@string/hello_world" />

This facility can also be used to create references between resources. For example, we can create new

drawable resources that are aliases for existing images:

<?xml version="1.0" encoding="utf-8"?>

<resources>

<drawable

id="my_background">@android:drawable/theme2_background</drawable>

</resources>

Another kind of resource value allows you to reference the value of an attribute in the current theme. This

attribute reference can only be used in style resources and XML attributes; it allows you to customize the look

of UI elements by changing them to standard variations supplied by the current theme, instead of supplying

more concrete values.

As an example, we can use this in our layout to set the text color to one of the standard colors defined in the

base system theme:

<?xml version="1.0" encoding="utf-8"?>

<EditText id="text"

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent" android:layout_height="fill_parent"

android:textColor="?android:textDisabledColor" android:text="@string/hello_world" />

References to Theme Attributes

Note that this is very similar to a resource reference, except we are using an '?' prefix instead of '@'. When

you use this markup, you are supplying the name of an attribute resource that will be looked up in the theme --

because the resource tool knows that an attribute resource is expected, you do not need to explicitly state the

type (which would be ?android:attr/android:textDisabledColor ).

Other than using this resource identifier to find the value in the theme instead of raw resources, the name

syntax is identical to the '@' format: ?[namespace:]type/name with the type here being optional.

87Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 89: Documentation Android

Many resources included with the system are available to applications. All such resources are defined under

the class "android.R". For example, you can display the standard application icon in a screen with the

following code:

public class MyActivity extends Activity

{

public void onStart()

{

requestScreenFeatures (FEATURE_BADGE_IMAGE);

super.onStart();

setBadgeResource(android.R.drawable.sym_def_app_icon);

}

}

In a similar way, this code will apply to your screen the standard "green background" visual treatment defined

by the system:

public class MyActivity extends Activity

{

public void onStart()

{

super.onStart();

setTheme(android.R.style.Theme_Black);

}

}

You can supply different resources for your product according to the UI language or hardware configuration on

the device. Note that although you can include different string, layout, and other resources, the SDK does not

expose methods to let you specify which alternate resource set to load. Android detects the proper set for the

hardware and location, and loads them as appropriate. Users can select alternate language settings using the

settings panel on the device.

To include alternate resources, create parallel resource folders with qualifiers appended to the folder names,

indicating the configuration it applies to (language, screen orientation, and so on). For example, here is a

project that holds one string resource file for English, and another for French:

Using System Resources

Supporting Alternate Resources for Alternate Languages and Configurations

MyApp/

res/

values-en/

strings.xml

values-fr/

strings.xml

88Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 90: Documentation Android

Android supports several types of qualifiers, with various values for each. Append these to the end of the

resource folder name, separated by dashes. You can add multiple qualifiers to each folder name, but they

must appear in the order they are listed here. For example, a folder containing drawable resources for a fully

specified configuration would look like:

MyApp/

res/

drawable-en-rUS-port-160dpi-finger-qwerty-dpad-480x320/

More typically, you will only specify a few specific configuration options that a resource is defined for. You may

drop any of the values from the complete list, as long as the remaining values are still in the same order:

MyApp/

res/

drawable-en-rUS-finger/

drawable-port/

drawable-port-160dpi/

drawable-qwerty/

Qualifier Values

Language The two letter ISO 639-1 language code in lowercase. For example: en, fr, es

Region The two letter ISO 3166-1-alpha-2 language code in uppercase preceded by a

lowercase "r". For example: rUS, rFR, rES

Screen orientation port, land, square

Screen pixel density 92dpi, 108dpi, etc.

Touchscreen type notouch, stylus, finger

Primary text input

method

qwerty, 12key

Primary

non-touchscreen

navigation method

dpad, trackball, wheel

Screen dimensions 320x240, 640x480, etc. The larger dimension must be specified first.

This list does not include device-specific parameters such as carrier, branding, device/hardware, or

manufacturer. Everything that an application needs to know about the device that it is running on is encoded

via the resource qualifiers in the table above.

Here are some general guidelines on qualified resource directory names:

Values are separated by a dash (as well as a dash after the base directory name)

Values are case-sensitive (even though they must be unique across all folder names in a

case-insensitive way)

For example,

A portrait-specific drawable directory must be named drawable-port , not drawable-PORT .

You may not have two directories named drawable-port and drawable-PORT , even if you had

intended "port" and "PORT" to refer to different parameter values.

89Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 91: Documentation Android

Only one value for each qualifier type is supported (that is, you cannot specify drawable-rEN-rFR/ )

You can specify multiple parameters in any order to define specific configurations. For example,

drawable-land-en-rUS will apply to landscape view, US-English devices.

Android will try to find the most specific matching directory for the current configuration, as described

below

The order of parameters listed in this table is used to break a tie in case of multiple qualified directories

(see the example given below)

All directories, both qualified and unqualified, live under the res/ folder. Qualified directories cannot be

nested (you cannot have res/drawable/drawable-en )

All resources will be referenced in code or resource reference syntax by their simple, undecorated

name. So if a resource is named this:

MyApp/res/drawable-port-92dp/myimage.png

It would be referenced as this:

R.drawable.myimage (code)

@drawable/myimage (XML)

Android will pick which of the various underlying resource files should be used at runtime, depending on the

current configuration. The selection process is as follows:

Eliminate any resources whose configuration does not match the current device configuration. For

example, if the screen pixel density is 108dpi, this would eliminate only

MyApp/res/drawable-port-92dpi/ .

MyApp/res/drawable/myimage.png

MyApp/res/drawable-en/myimage.png

MyApp/res/drawable-port/myimage.png

MyApp/res/drawable-port-92dpi/myimage.png

1.

Pick the resources with the highest number of matching configurations. For example, if our locale is

en-GB and orientation is port, then we have two candidates with one matching configuration each:

MyApp/res/drawable-en/ and MyApp/res/drawable-port/ . The directory

MyApp/res/drawable/ is eliminated because it has zero matching configurations, while the others

have one matching configuration.

MyApp/res/drawable/myimage.png

MyApp/res/drawable-en/myimage.png

MyApp/res/drawable-port/myimage.png

2.

Pick the final matching file based on configuration precedence, which is the order of parameters listed in3.

How Android finds the best matching directory

the table above. That is, it is more important to match the language than the orientation, so we break the

tie by picking the language-specific file, MyApp/res/drawable-en/ .

MyApp/res/drawable-en/myimage.png

MyApp/res/drawable-port/myimage.png

90Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 92: Documentation Android

The resource system brings a number of different pieces together to form the final complete resource

functionality. To help understand the overall system, here are some brief definitions of the core concepts and

components you will encounter in using it:

Asset: A single blob of data associated with an application. This includes object files compiled from the Java

source code, graphics (such as PNG images), XML files, etc. These files are organized in a directory

hierarchy that, during final packaging of the application, is bundled together into a single ZIP file.

aapt: Android Asset Packaging Tool. The tool that generates the final ZIP file of application assets. In addition

to collecting raw assets together, it also parses resource definitions into binary asset data.

Resource Table: A special asset that aapt generates for you, describing all of the resources contained in an

application/package. This file is accessed for you by the Resources class; it is not touched directly by

applications.

Resource: An entry in the Resource Table describing a single named value. Broadly, there are two types of

resources: primitives and bags.

Resource Identifier: In the Resource Table all resources are identified by a unique integer number. In source

code (resource descriptions, XML files, Java source code) you can use symbolic names that stand as

constants for the actual resource identifier integer.

Primitive Resource: All primitive resources can be written as a simple string, using formatting to describe a

variety of primitive types included in the resource system: integers, colors, strings, references to other

resources, etc. Complex resources, such as bitmaps and XML describes, are stored as a primitive string

resource whose value is the path of the underlying Asset holding its actual data.

Bag Resource: A special kind of resource entry that, instead of a simple string, holds an arbitrary list of

name/value pairs. Each name is itself a resource identifier, and each value can hold the same kinds of string

formatted data as a normal resource. Bags also support inheritance: a bag can inherit the values from another

bag, selectively replacing or extending them to generate its own contents.

Kind: The resource kind is a way to organize resource identifiers for various purposes. For example, drawable

resources are used to instantiate Drawable objects, so their data is a primitive resource containing either a

color constant or string path to a bitmap or XML asset. Other common resource kinds are string (localized

string primitives), color (color primitives), layout (a string path to an XML asset describing a view layout), and

style (a bag resource describing user interface attributes). There is also a standard "attr" resource kind, which

defines the resource identifiers to be used for naming bag items and XML attributes

Style: The name of the resource kind containing bags that are used to supply a set of user interface attributes.

For example, a TextView class may be given a style resource that defines its text size, color, and alignment. In

a layout XML file, you associate a style with a bag using the "style" attribute, whose value is the name of the

style resource.

Style Class: Specifies a related set of attribute resources. This data is not placed in the resource table itself,

but used to generate constants in the source code that make it easier for you to retrieve values out of a style

resource and/or XML tag's attributes. For example, the Android platform defines a "View" style class that

Terminology

contains all of the standard view attributes: padding, visibility, background, etc.; when View is inflated it uses

this style class to retrieve those values from the XML file (at which point style and theme information is applied

as approriate) and load them into its instance.

Configuration: For any particular resource identifier, there may be multiple different available values

depending on the current configuration. The configuration includes the locale (language and country), screen

orientation, screen density, etc. The current configuration is used to select which resource values are in effect

when the resource table is loaded.

91Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 93: Documentation Android

Theme: A standard style resource that supplies global attribute values for a particular context. For example,

when writing an Activity the application developer can select a standard theme to use, such as the

Theme.White or Theme.Black styles; this style supplies information such as the screen background

image/color, default text color, button style, text editor style, text size, etc. When inflating a layout resource,

most values for widgets (the text color, selector, background) if not explicitly set will come from the current

theme; style and attribute values supplied in the layout can also assign their value from explicitly named

values in the theme attributes if desired.

Overlay: A resource table that does not define a new set of resources, but instead replaces the values of

resources that are in another resource table. Like a configuration, this is applied at load time to the resource

data; it can add new configuration values (for example strings in a new locale), replace existing values (for

example change the standard white background image to a "Hello Kitty" background image), and modify

resource bags (for example change the font size of the Theme.White style to have an 18 pt font size). This is

the facility that allows the user to select between different global appearances of their device, or download

files with new appearances.

The Resource Reference document provides a detailed list of the various types of resource and how to use

them from within the Java source code, or from other references.

Coming Soon: Internationalization and Localization are critical, but are also not quite ready yet in this early

look at the SDK. As the SDK matures, this section will contain information on the Internationalization and

Localization features of the Android platform. In the meantime, it is a good idea to start by externalizing all

strings, and practicing good structure in creating and using resources.

Resource Reference

Internationalization and Localization

92Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 94: Documentation Android

If you've read Getting Started and Developing Apps, then you know how to build an Android application. (If you haven't read

those sections you should now.)

Android is a large system though, and there's a lot to learn. The best apps always make the most of the system's features.

The links below tell you how to write code that bends the system to your will, allowing you to create cool custom components

and do amazing things with the many available APIs.

Design Philosophy

A manifesto explaining a technical philosophy and perspective that Android developers will find useful. By reading this

page, you'll learn how to write applications that perform well on embedded devices (such as phone handsets), and that

play nicely with other parts of the system.

Building Custom Components

Explains how to create custom Android components, such as Views, Services, and Content Providers. Read this, and

you'll soon be knocking out great-looking, efficient, and useful components. You can use these to make your own

application great, or you can share them with other applications.

Optional APIs

Describes the APIs that provide access to optional Android components, such as GPS and BlueTooth. Android aims to

be more than just another OS, and so the system supports all the features you could hope for in a phone. This section

will show you how to use the Location-Based Services (such as GPS, compass, etc.), OpenGL 3D graphics, Bluetooth,

and accelerometer.

Note that the APIs described in this section are all optional; if your application truly requires one of these APIs, you

should be sure that it fails gracefully if the features are not present on a given phone.

Google APIs and Services

Describes how to use the APIs for accessing Google services that are installed on many Android devices.

Android Developer Toolbox

The process of learning how to build applications for a new API is pretty similar, even if the platforms themselves are wildly

different. Generally, there are two phases: first, you learn how to use the APIs to do what you want to do; later, you learn the

nuances of the platform. Put another way, first you learn how you can build applications; later, you learn how you should

build them.

That second phase — learning the right way to build applications — can often take a long time, and frequently means

"paying your dues", making mistakes, and learning from them. Well, that's not a very efficient process, so this page and the

links below aim to give you a helping hand.

Before we dive into it, a quick word. Successful applications will offer an outstanding end-user experience. While the Android

team has built a robust core system, the vast majority of the user experience will come from users interacting with your

applications. As a result, we encourage you to take the time to build an outstanding user experience.

An outstanding user experience has three key characteristics: it is fast; it is responsive; and it is seamless. Of course every

platform since the dawn of computing has probably cited those same three qualities at one time or another. However, each

platform achieves them in different ways; the information below explains how your apps can achieve them on Android.

Android Application Design Philosophy

An Android application should be fast. Well, it's probably more accurate to say that it should be efficient. There is a tendency

in the computing world these days to assume that Moore's Law will solve all our problems — eventually. When it comes to

embedded applications, though, Moore's Law is a bit more complicated.

Moore's Law doesn't really apply to mobile devices in the same way as to desktop and server applications. Moore's Law is

actually a law about transistor density — that is, it says that you can pack more circuitry into a given chip size, over time. For

desktop and server applications, this means you can pack more "speed" into a chip of roughly the same size, resulting in the

well-known performance increases. For embedded applications like cell phones, however, Moore's Law is usually exploited

to make chips smaller. That is, the tendency is to use the increased density to make the same chip smaller and consume

less power, to make phones smaller and make batteries last longer. As a result, embedded devices like phones are

increasing in actual, raw speed much more slowly than desktop systems. For embedded devices, Moore's Law means more

features and better battery life; increased speed is only an afterthought.

Fast

93Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 95: Documentation Android

That's why it's important to write efficient code: you can't assume that phones will see the same speed increases as

desktops and servers. Generally speaking, writing fast code means keeping memory allocations to a minimum, writing tight

code, and avoiding certain language and programming idioms that can subtly cripple performance. In object-oriented terms,

most of this work takes place at the method level, on the order of actual lines of code, loops, and so on.

The article on Writing Efficient Android Code will give you all the detail you need to write fast, efficient code for Android.

It's possible to write code that wins every performance test in the world, but that still sends users in a fiery rage when they try

to use it. These are the applications that aren't responsive enough — the ones that feel sluggish, hang or freeze for

significant periods, or take too long to process input. In Android terms, applications that are insufficiently responsive will

frequently cause the system to pop up the dreaded "Application Not Responding" (ANR) message.

Generally, this happens if your application cannot respond to user input. For example, if your application blocks on some I/O

operation (frequently a network access), then the main application thread won't be able to process incoming user input

events. After a time the system will conclude that your application has hung, and give the user the option to kill it. Similarly, if

your application spends too much time building an elaborate in-memory structure, or perhaps computing the next move in a

game, then again the system will conclude that your application has hung. It's always important to make sure these

computations are efficient using the techniques above, but even the most efficient code still takes time to run.

Responsive

In both of these cases, the fix is usually to create a child thread, and do most of your work there. This keeps the main thread

(which drives the user interface event loop) running, and prevents the system from concluding your code has frozen. Since

such threading usually is accomplished at the class level, you can think of responsiveness as a class problem. (Compare

this with basic performance, which was described above as a method-level concern.)

The article on Building Responsive Android Applications discusses responsiveness in detail.

Even if your application is fast and responsive, it can still annoy users. A common example is a background process (such

as an Android Service or IntentReceiver) that pops up a UI in response to some event. This may seem harmless, and

frequently developers assume that this is okay because they spend most of their time testing and using their own

application. However, Android's application model is constructed explicitly to allow users to fluidly switch between

applications. This means that when your background process actually fires up that UI, the user could be way over in another

part of the system, doing something else — such as taking a phone call. Imagine if the SMS service popped up a dialog box

every time a text message came in; this would annoy users in no time. That's why the Android standard is to use

Notifications for such events; this leaves the user in control.

That's just one example; there are many more. For example, if Activities don't correctly implement the onPause() and other

lifecycle methods, this will frequently result in data loss. Or, if your application exposes data intended to be used by other

applications, you should expose it via a ContentProvider, rather than (for example) using a world-readable raw file or

database.

What those examples have in common is that they involve cooperating nicely with the system and other applications. The

Android system is designed to treat applications as a sort of federation of loosely-coupled components, rather than chunks

of black-box code. This allows you as the developer to view the entire system as just an even-larger federation of these

components. This benefits you by allowing you to integrate cleanly and seamlessly with other applications, and so you

should design your own code to return the favor.

This is a component-level concept (as opposed to the class- and method-level concepts of performance and

responsiveness, described above.) The article on Integrating with the System provides tips and best practices for writing

code that cooperates nicely with the rest of the system.

Seamless

In this article, we'll cover how Android determines if an application is not responding (hereafter called ANR), the causes of

ANR, and guidelines for ensuring that your application is responsive. There are a set of best practices — in addition to

writing efficient Android code — that will help ensure that your application's user interface is responsive. But before delving

into the details, here's a screenshot of what the dialog box created by Android when an application is not responding looks

like:

Developing Responsive Applications

94Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 96: Documentation Android

In Android, application responsiveness is monitored by the Activity Manager and Window Manager system services. Android

will display the ANR dialog for a particular application when it detects one of the following conditions:

no response to an input event (e.g. key press, screen touch) within 5 seconds

an IntentReceiver hasn't finished executing within 10 seconds

Given the above definition for ANR, let's examine why this can occur in Android applications and how best to structure your

application to avoid ANR.

Android applications normally run entirely on a single (i.e. main) thread. This means that anything your application is doing in

the main thread that takes a long time to complete can trigger the ANR dialog because your application is not giving itself a

chance to handle the input event or Intent broadcast.

Therefore any method that runs in the main thread should do as little work as possible. In particular, Activities should do as

little as possible to set up in key lifecycle methods such as onCreate() and onResume(). Potentially long running

operations such as network or database operations, or computationally expensive calculations such as resizing bitmaps

should be done in a child thread (or in the case of databases operations, via an asynchronous request). However, this does

not mean that your main thread should block while waiting for the child thread to complete — nor should you call

Thread.wait() or Thread.sleep(). Instead of blocking while waiting for a child thread to complete, your main thread

should provide a Handler for child threads to post back to upon completion. Designing your application in this way will allow

your main thread to remain responsive to input and thus avoid ANR dialogs caused by the 5 second input event timeout.

These same practices should be followed for any other threads that display UI, as they are also subject to the same

timeouts.

The specific constraint on IntentReciever execution time emphasizes what they were meant to do: small, discrete amounts

of work in the background such as saving a setting or registering a Notification. So as with other methods called in the main

When Good Applications Go Bad

Avoiding ANR

thread, applications should avoid potentially long-running operations or calculations in IntentReceivers. But instead of doing

intensive tasks via child threads (as the life of an IntentReceiver is short), your application should start a Service if a

potentially long running action needs to be taken in response to an Intent broadcast. As a side note, you should also avoid

starting an Activity from an Intent Receiver, as it will spawn a new screen that will steal focus from whatever application the

user is currently has running. If your application has something to show the user in response to an Intent broadcast, it should

do so using the Notification Manager.

Generally, 100 to 200ms is the threshold beyond which users will perceive lag (or lack of "snappiness," if you will) in an

application. As such, here are some additional tips beyond what you should do to avoid ANR that will help make your

application seem responsive to users.

If your application is doing work in the background in response to user input, show that progress is being made

(ProgressBar and ProgressDialog are useful for this).

For games specifically, do calculations for moves in a child thread.

If your application has a time-consuming initial setup phase, consider showing a splash screen or rendering the main

view as quickly as possible and filling in the information asynchronously. In either case, you should indicate somehow

that progress is being made, lest the user perceive that the application is frozen.

Reinforcing Responsiveness

There's no way around it: Android devices are embedded devices. Modern handsets may be more like small handheldcomputers than mere phones these days, but even the fastest, highest-end handset doesn't even come close to thecapabilities of even a modest desktop system.

That's why it's very important to consider performance when you write Android applications. These systems are not that fastto begin with and they are also constrained by their battery life. This means that there's not a lot of horsepower to spare, sowhen you write Android code it's important to write it as efficiently as possible.

This page describes a number of things that developers can do to make their Android code run more efficiently. By followingthe tips on this page, you can help make sure your code runs as efficiently as possible.

Writing Efficient Android Code

95Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 97: Documentation Android

There are two basic rules for resource-constrained systems:

Don't do work that you don't need to do.

Don't allocate memory if you can avoid it.

All the tips below follow from these two basic tenets.

Some would argue that much of the advice on this page amounts to "premature optimization." While it's true thatmicro-optimizations sometimes make it harder to develop efficient data structures and algorithms, on embedded devices likehandsets you often simply have no choice. For instance, if you bring your assumptions about VM performance on desktopmachines to Android, you're quite likely to write code that exhausts system memory. This will bring your application to acrawl — let alone what it will do to other programs running on the system!

That's why these guidelines are important. Android's success depends on the user experience that your applicationsprovide, and that user experience depends in part on whether your code is responsive and snappy, or slow and aggravating.Since all our applications will run on the same devices, we're all in this together, in a way. Think of this document as like therules of the road you had to learn when you got your driver's license: things run smoothly when everybody follows them, butwhen you don't, you get your car smashed up.

Before we get down to brass tacks, a brief observation: nearly all issues described below are valid whether or not the VMfeatures a JIT compiler. If I have two methods that accomplish the same thing, and the interpreted execution of foo() is faster

Introduction

than bar(), then the compiled version of foo() will probably be as fast or faster than compiled bar(). It is unwise to rely on acompiler to "save" you and make your code fast enough.

Object creation is never free. A generational GC with per-thread allocation pools for temporary objects can make allocationcheaper, but allocating memory is always more expensive than not allocating memory.

If you allocate objects in a user interface loop, you will force a periodic garbage collection, creating little "hiccups" in the userexperience.

Thus, you should avoid creating object instances you don't need to. Some examples of things that can help:

When extracting strings from a set of input data, try to return a substring of the original data, instead of creating a copy.You will create a new String object, but it will share the char[] with the data.

If you have a method returning a string, and you know that its result will always be appended to a StringBuffer anyway,change your signature and implementation so that the function does the append directly, instead of creating ashort-lived temporary object.

A somewhat more radical idea is to slice up multidimensional arrays into parallel single one-dimension arrays:

An array of ints is a much better than an array of Integers, but this also generalizes to the fact that two parallel arraysof ints are also a lot more efficient than an array of (int,int) objects. The same goes for any combination of primitivetypes.

If you need to implement a container that stores tuples of (Foo,Bar) objects, try to remember that two parallel Foo[] andBar[] arrays are generally much better than a single array of custom (Foo,Bar) objects. (The exception to this, ofcourse, is when you're designing an API for other code to access; in those cases, it's usually better to trade correct APIdesign for a small hit in speed. But in your own internal code, you should try and be as efficient as possible.)

Generally speaking, avoid creating short-term temporary objects if you can. Fewer objects created mean less-frequentgarbage collection, which has a direct impact on user experience.

Avoid Creating Objects

When processing strings, don't hesitate to use specialty methods like String.indexOf(), String.lastIndexOf(), and theircousins. These are typically implemented in C/C++ code that easily runs 10-100x faster than doing the same thing in a Javaloop.

The flip side of that advice is that calling punching through to a native method is more expensive than calling an interpretedmethod. Don't use native methods for trivial computation, if you can avoid it.

Use Native Methods

96Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 98: Documentation Android

Suppose you have a HashMap object. You can declare it as a HashMap or as a generic Map:

Map myMap1 = new HashMap();

HashMap myMap2 = new HashMap();

Which is better?

Conventional wisdom says that you should prefer Map, because it allows you to change the underlying implementation toanything that implements the Map interface. Conventional wisdom is correct for conventional programming, but isn't so greatfor embedded systems. Calling through an interface reference can take 2x longer than a virtual method call through aconcrete reference.

If you have chosen a HashMap because it fits what you're doing, there is little value in calling it a Map. Given the availabilityof IDEs that refactor your code for you, there's not much value in calling it a Map even if you're not sure where the code isheaded. (Again, though, public APIs are an exception: a good API usually trumps small performance concerns.)

Prefer Virtual Over Interface

If you don't need to access an object's fields, make your method static. It can be called faster, because it doesn't require avirtual method table indirection. It's also good practice, because you can tell from the method signature that calling themethod can't alter the object's state.

In native languages like C++ it's common practice to use getters (e.g. i = getCount()) instead of accessing the field

directly (i = mCount). This is an excellent habit for C++, because the compiler can usually inline the access, and if you

need to restrict or debug field access you can add the code at any time.

On Android, this is a bad idea. Virtual method calls are expensive, much more so than instance field lookups. It's reasonableto follow common object-oriented programming practices and have getters and setters in the public interface, but within aclass you should always access fields directly.

Prefer Static Over Virtual

Avoid Internal Getters/Setters

Accessing object fields is much slower than accessing local variables. Instead of writing:

for (int i = 0; i < this.mCount; i++)

dumpItem(this.mItems[i]);

You should write:

int count = this.mCount;

Item[] items = this.mItems;

for (int i = 0; i < count; i++)

dumpItems(items[i]);

(We're using an explicit "this" to make it clear that these are member variables.)

Cache Field Lookups

A similar guideline is never call a method in the second clause of a "for" statement. For example, the following code willexecute the getCount() method once per iteration, which is a huge waste when you could have simply cached the value asan int:

for (int i = 0; i < this.getCount(); i++)

dumpItems(this.getItem(i));

97Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 99: Documentation Android

It's also usually a good idea to create a local variable if you're going to be accessing an instance field more than once. Forexample:

protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) {

if (isHorizontalScrollBarEnabled()) {

int size = mScrollBar.getSize(false);

if (size <= 0) {

size = mScrollBarSize;

}

mScrollBar.setBounds(0, height - size, width, height);

mScrollBar.setParams(

computeHorizontalScrollRange(),

computeHorizontalScrollOffset(),

computeHorizontalScrollExtent(), false);

mScrollBar.draw(canvas); } }

That's four separate lookups of the member field mScrollBar. By caching mScrollBar in a local stack variable, the four

member field lookups become four stack variable references, which are much more efficient.

Incidentally, method arguments have the same performance characteristics as local variables.

Consider the following declaration at the top of a class:

static int intVal = 42;

static String strVal = "Hello, world!";

The compiler generates a class initializer method, called <clinit>, that is executed when the class is first used. The

method stores the value 42 into intVal, and extracts a reference from the classfile string constant table for strVal. When

these values are referenced later on, they are accessed with field lookups.

We can improve matters with the "final" keyword:

static final int intVal = 42;

static final String strVal = "Hello, world!";

The class no longer requires a <clinit> method, because the constants go into classfile static field initializers, which are

handled directly by the VM. Code accessing intVal will use the integer value 42 directly, and accesses to strVal will use

a relatively inexpensive "string constant" instruction instead of a field lookup.

Declaring a method or class "final" does not confer any immediate performance benefits, but it does allow certainoptimizations. For example, if the compiler knows that a "getter" method can't be overridden by a sub-class, it can inline themethod call.

You can also declare local variables final. However, this has no definitive performance benefits. For local variables, only use"final" if it makes the code clearer (or you have to, e.g. for use in an anonymous inner class).

Declare Constants Final

foreach can be used for collections that implement the Iterable interface. With these objects, foreach allocates an iterator,and makes interface calls to hasNext() and next(). With an ArrayList, you're better off walking through it directly, but for othercollections the foreach syntax will be equivalent to explicit iterator usage.

Use foreach Syntax With Caution

98Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 100: Documentation Android

However, the following code shows an acceptable use of foreach:

public class Foo {

int mSplat;

static Foo mArray[] = new Foo[27];

public static void zero() {

int sum = 0;

for (int i = 0; i < mArray.length; i++) {

sum += mArray[i].mSplat;

}

}

public static void one() {

int sum = 0;

Foo[] localArray = mArray;

int len = localArray.length;

for (int i = 0; i < len; i++) {

sum += localArray[i].mSplat;

}

}

public static void two() {

int sum = 0;

for (Foo a: mArray) {

sum += a.mSplat;

}

}

}

zero() retrieves the static field twice and gets the array length once for every iteration through the loop.

one() pulls everything out into local variables, avoiding the lookups.

two() uses the foreach syntax introduced in version 1.5 of the Java programming language. The code generated by thecompiler takes care of copying the array reference and the array length to local variables, making it a good choice forwalking through all elements of an array. It does generate an extra local load/store in the main loop (apparently preserving"a"), making it a teensy bit slower and 4 bytes longer than one().

To summarize all that a bit more clearly: "foreach" syntax performs well with arrays, but be cautious when using it withIterable objects since there is additional object creation.

Enums are very convenient, but unfortunately can be painful when size and speed matter. For example, this:

public class Foo {

public enum Shrubbery { GROUND, CRAWLING, HANGING }

}

turns into a 900 byte .class file (Foo$Shubbery.class). On first use, the class initializer invokes the <init> method on objectsrepresenting each of the enumerated values. Each object gets its own static field, and the full set is stored in an array (astatic field called "$VALUES"). That's a lot of code and data, just for three integers.

Avoid Enums

This:

Shrubbery shrub = Shrubbery.GROUND;

causes a static field lookup. If "GROUND" were a static final int, the compiler would treat it as a known constant and inline it.

99Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 101: Documentation Android

The flip side, of course, is that with enums you get nicer APIs and some compile-time value checking. So, the usual trade-offapplies: you should by all means use enums for public APIs, but try to avoid them when performance matters.

In some circumstances it can be helpful to get enum integer values through the ordinal() method. For example, replace:

for (int n = 0; n < list.size(); n++) {

if (list.items[n].e == MyEnum.VAL_X)

// do stuff 1

else if (list.items[n].e == MyEnum.VAL_Y)

// do stuff 2

}

with:

int valX = MyEnum.VAL_X.ordinal();

int valY = MyEnum.VAL_Y.ordinal();

int count = list.size();

MyItem items = list.items();

for (int n = 0; n < count; n++)

{

int valItem = items[n].e.ordinal();

if (valItem == valX)

// do stuff 1

else if (valItem == valY)

// do stuff 2

}

In some cases, this will be faster, though this is not guaranteed.

Consider the following class definition:

public class Foo {

private int mValue;

public void run() {

Inner in = new Inner();

mValue = 27;

in.stuff();

}

private void doStuff(int value) {

System.out.println("Value is " + value);

}

private class Inner {

void stuff() {

Foo.this.doStuff(Foo.this.mValue);

}

}

}

The key things to note here are that we define an inner class (Foo$Inner) that directly accesses a private method and aprivate instance field in the outer class. This is legal, and the code prints "Value is 27" as expected.

The problem is that Foo$Inner is technically (behind the scenes) a totally separate class, which makes direct access toFoo's private members illegal. To bridge that gap, the compiler generates a couple of synthetic methods:

Use Package Scope with Inner Classes

100Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 102: Documentation Android

/*package*/ static int Foo.access$100(Foo foo) {

return foo.mValue;

}

/*package*/ static void Foo.access$200(Foo foo, int value) {

foo.doStuff(value);

}

The inner-class code calls these static methods whenever it needs to access the "mValue" field or invoke the "doStuff"method in the outer class. What this means is that the code above really boils down to a case where you're accessingmember fields through accessor methods instead of directly. Earlier we talked about how accessors are slower than directfield accesses, so this is an example of a certain language idiom resulting in an "invisible" performance hit.

We can avoid this problem by declaring fields and methods accessed by inner classes to have package scope, rather thanprivate scope. This runs faster and removes the overhead of the generated methods. (Unfortunately it also means the fieldscould be accessed directly by other classes in the same package, which runs counter to the standard OO practice of makingall fields private. Once again, if you're designing a public API you might want to carefully consider using this optimization.)

Before the release of the Pentium CPU, it was common for game authors to do as much as possible with integer math. Withthe Pentium, the floating point math co-processor became a built-in feature, and by interleaving integer and floating-pointoperations your game would actually go faster than it would with purely integer math. The common practice on desktopsystems is to use floating point freely.

Unfortunately, embedded processors frequently do not have hardware floating point support, so all operations on "float" and"double" are performed in software. Some basic floating point operations can take on the order of a millisecond to complete.

Also, even for integers, some chips have hardware multiply but lack hardware divide. In such cases, integer division andmodulus operations are performed in software — something to think about if you're designing a hash table or doing lots ofmath.

Avoid Float

To illustrate some of our ideas, here is a table listing the approximate run times for a few basic actions. Note that thesevalues should NOT be taken as absolute numbers: they are a combination of CPU and wall clock time, and will change asimprovements are made to the system. However, it is worth noting how these values apply relative to each other — forexample, adding a member variable currently takes about four times as long as adding a local variable.

Action Time

Add a local variable 1

Add a member variable 4

Call String.length() 5

Call empty static native method 5

Call empty static method 12

Call empty virtual method 12.5

Call empty interface method 15

Call Iterator:next() on a HashMap 165

Call put() on a HashMap 600

Inflate 1 View from XML 22,000

Inflate 1 LinearLayout containing 1 TextView 25,000

Inflate 1 LinearLayout containing 6 View objects 100,000

Inflate 1 LinearLayout containing 6 TextView objects 135,000

Launch an empty activity 3,000,000

Some Sample Performance Numbers

101Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 103: Documentation Android

The best way to write good, efficient code for embedded systems is to understand what the code you write really does. If you

Closing Notes

really want to allocate an iterator, by all means use foreach syntax on a List; just make it a deliberate choice, not aninadvertent side-effect.

Forewarned is forearmed! Know what you're getting into! Insert your favorite maxim here, but always think carefully aboutwhat your code is doing, and be on the lookout for ways to speed it up.

Always keep in mind that Android is a phone platform. It may seem obvious to say it, but it's important to remember that

another Activity (such as the "Incoming Phone Call" app) can pop up over your own Activity at any moment. This will fire the

onFreeze() and onPause() methods, and will likely result in your application being killed.

If the user was editing data in your application when the other Activity appeared, your application will likely lose that data

when your application is killed. Unless, of course, you save the work in progress first. The "Android Way" is to do just that:

Android applications that accept or edit input should override the onFreeze() method and save their state in some

appropriate fashion. When the user revisits the application, she should be able to retrieve her data.

A classic example of a good use of this behavior is a mail application. If the user was composing an email when another

Activity started up, the application should save the in-process email as a draft.

If you wouldn't walk down the street in your underwear, neither should your data. While it's possible to expose certain kinds

of application to the world to read, this is usually not the best idea. Exposing raw data requires other applications to

understand your data format; if you change that format, you'll break any other applications that aren't similarly updated.

The "Android Way" is to create a ContentProvider to expose your data to other applications via a clean, well-thought-out,

and maintainable API. Using a ContentProvider is much like inserting a Java language interface to split up and

componentize two tightly-coupled pieces of code. This means you'll be able to modify the internal format of your data without

changing the interface exposed by the ContentProvider, and this without affecting other applications.

If the user is running an application (such as the Phone application during a call) it's a pretty safe bet he did it on purpose.

That's why you should avoid spawning Activities except in direct response to user input from the current Activity.

That is, don't spawn Activities from IntentReceivers or Services running in the background. Doing so will interrupt whatever

application is currently running, and result in an annoyed user. Perhaps even worse, your Activity may become a "keystroke

bandit" and receive some of the input the user was in the middle of providing to the previous Activity. Depending on what

your application does, this could be bad news.

Instead of spawning Activities directly from the background, you should instead use the NotificationManager to set

Notifications. These will appear in the status bar, and the user can then click on them at his leisure, to see what your

application has to show him.

(Note that all this doesn't apply to cases where your own Activity is already in the foreground: in that case, the user expects

to see your next Activity in response to input.)

Writing Seamless Android Applications

Don't Drop Data

No One Wants to See Your Data Naked

Don't Interrupt the User When He's Talking

If your application needs to perform some expensive or long-running computation, you should probably move it to a thread.

This will prevent the dreaded "Application Not Responding" dialog from being displayed to the user, with the ultimate result

being the fiery demise of your application.

By default, all code in an Activity as well as all its Views runs in the same thread. This is the same thread that also handles

Got a Lot to Do? Take it to a Thread

102Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 104: Documentation Android

UI events. For example, when the user presses a key, a key-down event is added to the Activity's main thread's queue. Theevent handler system needs to dequeue and handle that event quickly; if it doesn't, the system concludes after a few

seconds that the application is hung and offers to kill it for the user.

If you have long-running code, running it inline in your Activity will run it on the event handler thread, effectively blocking the

event handler. This will delay input processing, and result in the ANR dialogs. To avoid this, move your computations to a

thread; click here to learn how.

Any application worth using will probably have several different screens. When partitioning your UI, be sure to make

effective use of Activities.

Depending on your development background, you may interpret an Activity as similar to something like a Java Applet, in that

it is the entry point for your application. However, that's not quite accurate: where an Applet subclass is the single entry point

for a Java Applet, an Activity should be thought of as one of potentially several entry points to your application. The only

difference between your "main" Activity and any others you might have is that the "main" one just happens to be the only one

that expressed an interest in the "android.intent.action.MAIN" action in your AndroidManifest..xml file.

So, when designing your application, think of your application as a federation of Activities. This will make your code a lot

more maintainable in the long run, and as a nice side effect also plays nicely with Android's application history and

"backstack" model.

When it comes to the look-and-feel of the user interface, it's important to blend in nicely. Users are jarred by applications

which contrast with the user interface they've come to expect. When designing your UIs, you should try and avoid rolling

your own as much as possible. Instead, use a Theme. You can override or extend those parts of the theme that you need to,

but at least you're starting from the same UI base as all the other applications. For all the details, click here.

Different Android devices will sport different resolutions. Some will even be able to change resolutions on the fly, such as by

switching to landscape mode. It's important to make sure your layouts and drawables are flexible.

Fortunately, this is very easy to do. Check out Implementing a User Interface for the full details, but in brief what you must do

is provide different versions of your artwork (if you use any) for the key resolutions, and then design your layout to

accommodate various dimensions. (For example, avoid using hard-coded positions and instead use relative layouts.) If you

do that much, the system handles the rest, and your application looks great on any device.

Android devices will come with a variety of network-connectivity options. All will have some data-access provision, though

some will be faster than others. The lowest common denominator, however, is GPRS, the non-3G data service for GSM

networks. Even 3G-capable devices will spend lots of time on non-3G networks, so slow networks will remain a reality for

quite a long time to come.

That's why you should always code your applications to minimize network accesses and bandwidth. You can't assume the

network is fast, so you should always plan for it to be slow. If your users happen to be on faster networks, then that's great

— their experience will only improve. You want to avoid the inverse case though: applications that are usable some of the

time, but frustratingly slow the rest based on where the user is at any given moment are likely to be unpopular.

One potential gotcha here is that it's very easy to fall into this trap if you're using the emulator, since the emulator uses your

desktop computer's network connection. That's almost guaranteed to be much faster than a cell network, so you'll want to

change the settings on the emulator that simulate slower network speeds. You can do this in Eclipse, in the "Emulator

Settings" tab of your launch configuration or via a command line option when starting the emulator.

Avoid Huge Activities

Extend Themes

Make Being Flexible part of your Resolutions

Assume the Network is Slow

Different Keystrokes for Different Folks

Android will support a variety of handset form-factors. That's a fancy way of saying that some Android devices will have full

"QWERTY" keyboards, while others will have 40-key, 12-key, or even other key configurations. Similarly, some devices will

have touch-screens, but many won't.

When building your applications, keep that in mind. Don't make assumptions about specific keyboard layouts -- unless, of

course, you're really interested in restricting your application so that it can only be used on those devices.

103Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 105: Documentation Android

A wireless device isn't very wireless if it's constantly plugged into the wall. Handheld devices are battery-powered, and the

longer we can make that battery last on a charge, the happier everyone is -- especially the user. Two of the biggest

consumers of battery power are the processor, and the radio; that's why it's important to write your applications to do as little

work as possible, and use the network as infrequently as possible.

Minimizing the amount of processor time your application uses really comes down to writing efficient code. To minimize the

power drain from using the radio, be sure to handle error conditions gracefully, and only fetch what you need. For example,

don't constantly retry a network operation if one failed. If it failed once, it's likely because the user has no reception, so it's

probably going to fail again if you try right away; all you'll do is waste battery power.

Users are pretty smart: if your program is power-hungry, you can count on them noticing. The only thing you can be sure of

at that point is that your program won't stay installed very long.

Don't Assault the Battery

Android comes with a solid collection of View components that you can use to construct your applications, e.g. Button,

TextView, EditText, ListView, CheckBox, RadioButton, Gallery, Spinner, and even some much more advanced and special

purpose Views like AutoCompleteTextView, ImageSwitcher, and TextSwitcher. The various layout managers like

LinearLayout, FrameLayout, and so forth are also considered Views and are descendents of the View class hierarchy.

You can combine these layouts and controls into a screen to display in your application, and much of the time this may be

enough for you, but you should also be aware that you can create custom components by extending Views, Layouts, and

even the advanced controls using inheritance. Some typical reasons for doing this might include:

To create a completely custom-rendered component, for example a "volume control" knob rendered using 2D

graphics, and which resembles an analog electronic control.

Combine a group of View components into a new single component, perhaps to make something like a ComboBox (a

combination of popup list and free entry text field), a dual-pane selector control (a left and right pane with a list in each

where you can re-assign which item is in which list), and so on.

To create your own kind of layout. The layouts provided in the SDK provide a good set of options for designing your

own applications, but advanced developers may find the need to provide a new layout that extends one of the existing

ones, or perhaps is entirely new.

Override the display or behavior of an existing component; for example, change the way that an EditText component is

rendered on the screen (the Notepad sample uses this to good effect to create a lined-notepad page).

Capture other events like key presses and handle them in some custom way (e.g. for a game).

There are many more reasons why you might want to extend an existing View to achieve some goal. This page will give you

some starting points on how to do it, and back it up with some examples.

These steps provide a high level overview of what you need to know to get started in creating your own components:

Extend an existing View class or subclass with your own class.1.

Override some of the methods from the superclass: the superclass methods to override start with ' on', for example,

onDraw(), onMeasure(), and onKeyDown().

This is similar to the on... events in Activity or ListActivity that you override for lifecycle and other functionality

hooks.

2.

Use your new extension class: once completed, your new extension class can be used in place of the view upon which

it was based, but now with the new functionality.

3.

Extension classes can be defined as inner classes inside the activities that use them. This is useful because it controls

access to them but isn't necessary (perhaps you want to create a new public component for wider use in your

Building Custom Android Components

The Basic Approach

application).

104Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 106: Documentation Android

Fully customized components can be used to create graphical components that appear however you wish. Perhaps a

graphical VU meter that looks like an old analog gauge, or a sing-a-long text view where a bouncing ball moves along the

words so you can sing along with a karaoke machine. Either way, you want something that the built-in components just won't

do, no matter how you combine them.

Fortunately, you can easily create components that look and behave in any way you like, limited perhaps only by your

imagination, the size of the screen, and the available processing power (remember that ultimately your application might

have to run on something with significantly less power than your desktop workstation).

To create a fully customized component:

The most generic view you can extend is, unsurprisingly, View, so you will usually start by extending this to create your

new super component.

1.

You can supply a constructor which can take attributes and parameters from the XML, and you can also consume your

own such attributes and parameters (perhaps the color and range of the VU meter, or the width and damping of the

needle, etc.)

2.

You will probably want to create your own event listeners, property accessors and modifiers, and possibly more

sophisticated behavior in your component class as well.

3.

You will almost certainly want to override onMeasure() and are also likely to need to override onDraw() if you want

the component to show something. While both have default behavior, the default onDraw() will do nothing, and the

default onMeasure() will always set a size of 100x100 — which is probably not what you want.

4.

Other on... methods may also be overridden as required.5.

onDraw() delivers you a Canvas upon which you can implement anything you want: 2D graphics, other standard or custom

components, styled text, or anything else you can think of. If you want to use 3D graphics, you should extend GLView

instead of View, but otherwise the same concepts apply.

onMeasure() is a little more involved. onMeasure() is a critical piece of the rendering contract between your component

and its container. onMeasure() should be overridden to efficiently and accurately report the measurements of its contained

parts. This is made slightly more complex by the requirements of limits from the parent (which are passed in to the

onMeasure() method) and by the requirement to call the setMeasuredDimension() method with the measured width

and height once they have been calculated. If you fail to call this method from an overridden onMeasure() method, the

result will be an exception at measurement time.

At a high level, implementing onMeasure() looks something like this:

The overridden onMeasure() method is called with width and height measure specifications (widthMeasureSpec

and heighMeasureSpec parameters, both are integer codes representing dimensions) which should be treated as

requirements for the restrictions on the width and height measurements you should produce. A full reference to the

kind of restrictions these specifications can require can be found in the reference documentation under

View.onMeasure(int, int) (this reference documentation does a pretty good job of explaining the whole measurement

operation as well).

1.

Your component's onMeasure() method should calculate a measurement width and height which will be required to

render the component. It should try to stay within the specifications passed in, although it can choose to exceed them

(in this case, the parent can choose what to do, including clipping, scrolling, throwing an exception, or asking the

onMeasure() to try again, perhaps with different measurement specifications).

2.

Once the width and height are calculated, the setMeasuredDimension(int width, int height) method must

be called with the calculated measurements. Failure to do this will result in an exception being thrown.

3.

The CustomView sample in the API Demos provides an example of a customized component. The custom component is

defined in the LabelView class.

The LabelView sample demonstrates a number of different aspects of custom components:

Extending the View class for a completely custom component.

Fully Customized Components

A Customized Component Example

onDraw() and onMeasure()

Parameterized constructor that takes the view inflation parameters (parameters defined in the XML). Some of these

are passed through to the View superclass, but more importantly, there are some custom attributes defined and used

for LabelView.

105Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 107: Documentation Android

Standard public methods of the type you would expect to see for a label component, for example setText(),

setTextSize(), setTextColor() and so on.

An overridden onMeasure method to determine and set the rendering size of the component. (Note that in LabelView,

the real work is done by a private measureWidth() method.)

An overridden onDraw() method to draw the label onto the provided canvas.

You can see some sample usages of the LabelView custom component in custom_view_1.xml from the samples. In

particular, you can see a mix of both android: namespace parameters and custom app: namespace parameters. These

app: parameters are the custom ones that the LabelView recognizes and works with, and are defined in a styleable inner

class inside of the samples R resources definition class.

If you don't want to create a completely customized component, but instead are looking to put together a reusable

component that consists of a group of existing controls, then creating a Compound Component (or Compound Control)

might fit the bill. In a nutshell, this brings together a number of more atomic controls (or views) into a logical group of items

that can be treated as a single thing. For example, a Combo Box can be thought of as a combination of a single line EditText

field and an adjacent button with an attached PopupList. If you press the button and select something from the list, it

populates the EditText field, but the user can also type something directly into the EditText if they prefer.

In Android, there are actually two other Views readily available to do this: Spinner and AutoCompleteTextView, but

regardless, the concept of a Combo Box makes an easy-to-understand example.

To create a Compound Component:

The usual starting point is a Layout of some kind, so create a class that extends a Layout. Perhaps in the case of a

Combo box we might use a LinearLayout with horizontal orientation. Remember that other layouts can be nested

inside, so the compound component can be arbitrarily complex and structured. Note that just like with an Activity, you

can use either the declarative (XML-based) approach to creating the contained components, or you can nest them

programmatically from your code.

1.

In the constructor for the new class, take whatever parameters the superclass expects, and pass them through to the

superclass constructor first. Then you can set up the other views to use within your new component; this is where you

would create the EditText field and the PopupList. Note that you also might introduce your own attributes and

parameters into the XML that can be pulled out and used by your constructor.

2.

You can also create listeners for events that your contained views might generate, for example, a listener method for

the List Item Click Listener to update the contents of the EditText if a list selection is made.

3.

You might also create your own properties with accessors and modifiers, for example, allow the EditText value to be

set initially in the component and query for its contents when needed.

4.

In the case of extending a Layout, you don't need to override the onDraw() and onMeasure() methods since the

layout will have default behavior that will likely work just fine. However, you can still override them if you need to.

5.

You might override other on... methods, like onKeyDown(), to perhaps choose certain default values from the

popup list of a combo box when a certain key is pressed.

6.

To summarize, the use of a Layout as the basis for a Custom Control has a number of advantages, including:

You can specify the layout using the declarative XML files just like with an activity screen, or you can create views

programmatically and nest them into the layout from your code.

The onDraw() and onMeasure() methods (plus most of the other on... methods) will likely have suitable behavior

so you don't have to override them.

In the end, you can very quickly construct arbitrarily complex compound views and re-use them as if they were a single

component.

In the API Demos project that comes with the SDK, there are two List examples — Example 4 and Example 6 under

Views/Lists demonstrate a SpeechView which extends LinearLayout to make a component for displaying Speech quotes.

The corresponding classes in the sample code are List4.java and List6.java.

Compound Components (or Compound Controls)

Examples of Compound Controls

106Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 108: Documentation Android

There is an even easier option for creating a custom component which is useful in certain circumstances. If there is a

component that is already very similar to what you want, you can simply extend that component and just override the

behavior that you want to change. You can do all of the things you would do with a fully customized component, but by

starting with a more specialized class in the View heirarchy, you can also get a lot of behavior for free that probably does

exactly what you want.

For example, the SDK includes a NotePad application in the samples. This demonstrates many aspects of using the Android

platform, among them is extending an EditText View to make a lined notepad. This is not a perfect example, and the APIs for

doing this might change from this early preview, but it does demonstrate the principles.

If you haven't done so already, import the NotePad sample into Eclipse (or just look at the source using the link provided). In

particular look at the definition of MyEditText in the NoteEditor.java file.

Some points to note here

The Definition

The class is defined with the following line:

public static class MyEditText extends EditText

It is defined as an inner class within the NoteEditor activity, but it is public so that it could be accessed as

NoteEditor.MyEditText from outside of the NoteEditor class if desired.

It is static, meaning it does not generate the so-called "synthetic methods" that allow it to access data from the

parent class, which in turn means that it really behaves as a separate class rather than something strongly related

to NoteEditor. This is a cleaner way to create inner classes if they do not need access to state from the outer

class, keeps the generated class small, and allows it to be used easily from other classes.

It extends EditText, which is the View we have chosen to customize in this case. When we are finished, the

new class will be able to substitute for a normal EditText view.

1.

Class Initialization

As always, the super is called first. Furthermore, this is not a default constructor, but a parameterized one. The

EditText is created with these parameters when it is inflated from an XML layout file, thus, our constructor needs to

both take them and pass them to the superclass constructor as well.

2.

Overridden Methods

In this example, there is only one method to be overridden: onDraw() — but there could easily be others needed

when you create your own custom components.

For the NotePad sample, overriding the onDraw() method allows us to paint the blue lines on the EditText view

canvas (the canvas is passed into the overridden onDraw() method). The super.onDraw() method is called before the

method ends. The superclass method should be invoked, but in this case, we do it at the end after we have painted the

lines we want to include.

3.

Use the Custom Component

We now have our custom component, but how can we use it? In the NotePad example, the custom component is used

directly from the declarative layout, so take a look at note_editor.xml in the res/layout folder.

<view xmlns:android="http://schemas.android.com/apk/res/android"

class="com.google.android.notepad.NoteEditor$MyEditText"

id="@+id/note"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@android:drawable/empty"

android:padding="10dip"

android:scrollbars="vertical"

android:fadingEdge="vertical" />

The custom component is created as a generic view in the XML, and the class is specified using the full package.

Note also that the inner class we defined is referenced using the NoteEditor$MyEditText notation which is a

standard way to refer to inner classes in the Java programming language.

4.

Tweaking an Existing Component

107Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 109: Documentation Android

The other attributes and parameters in the definition are the ones passed into the custom component constructor,

and then passed through to the EditText constructor, so they are the same parameters that you would use for an

EditText view. Note that it is possible to add your own parameters as well, and we will touch on this again below.

And that's all there is to it. Admittedly this is a simple case, but that's the point — creating custom components is only as

complicated as you need it to be.

A more sophisticated component may override even more on... methods and introduce some of its own helper methods,

substantially customizing its properties and behavior. The only limit is your imagination and what you need the component to

do.

As you can see, Android offers a sophisticated and powerful component model where just about anything is possible, from

simple tweaking of existing Views, to compound controls, to fully customized components. Combining these techniques, you

should be able to achieve the exact look you want for your Android application.

Go Forth and Componentize

Android is suitable for a wide variety of phones, from high-end smartphones on down. The core Android APIs will be

available on every Android phone, but there are a few APIs which have special concerns: the "optional" APIs.

These APIs are "optional" for two reasons. First, they're optional in the sense that you don't need to use them. For example,

you can't write an application without using the Activity and Intent APIs, but your application may not need to know where the

user is, and so you may not need the Location-Based Services API. In this sense, the LBS API is optional where the Activity

API is not.

Second, some of these are "optional" in the sense that a given handset may not support them. For instance, a given handset

may not have Bluetooth or WiFi hardware. In this case, the APIs for accessing those features will still be present, but they

won't work. That is, your application won't have trouble running or linking on a device that doesn't support an API you use,

because the classes will be present on the device. However, the implementations may not do anything, or may throw

exceptions when you actually try to use them. What exactly each API does on unsupported devices is described in the

documentation for that API; you should be sure to code your application to gracefully handle such cases.

Location-Based Services (LBS) allow software to obtain the phone's current location. This includes location obtained from

the Global Positioning System (GPS) satellite constellation, but it's not limited to that. For instance, other location-based

systems may come online in the future, and as they do, support for them can be added to this API.

The Media APIs are used to play media files. This includes both audio (such as playing MP3s or other music files, as well as

game sound effects) and video (such as playing a video downloaded over the web.) Support is included for "playing URIs"

— that is, streaming media data over the network.

Android's primary user interface framework is a typical widget-oriented class hierarchy. Don't let that fool you, though —

sitting underneath that is a very fast 2D and 3D compositing engine, with support for hardware acceleration. The API used to

access the 3D capabilities of the platform is the OpenGL ES API.

Android will include APIs for accessing low-level hardware such as Bluetooth and WiFi. These APIs, however, are not yet

available in the SDK. When they are released, this documentation will be updated.

Optional APIs in Android

Location-Based Services

Media APIs

3D Graphics with OpenGL

Low-Level Hardware Access

108Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com

Page 110: Documentation Android

Since Android is an open cell phone platform, anyone will be able to build their own devices that run the core Android OS.

There is no requirement that any given phone include any Google software, or even be associated with Google at all.

However, some groups may choose to license a set of optional user applications from Google that provide convenient

developer access to Google services. This will generally be a collection of software included in the base system image and

shipped with the phone.

Because many devices will include these libraries, for the convenience of developers we're including information about

those APIs here. However, please be aware that any APIs you use from the list below may not be available on all Android

devices. If the Google software is not present, these libraries and classes will not be present. As a result, if your application

uses these APIs, it may not install or run properly on devices that lack the APIs.

The MapView is an Android View that allows third-party code to display and control a Google Map. This is a complementary

offering to the MapActivity provided in the Google Maps application that other Activities can use to display maps of a specific

location. The table below summarizes the differences between the two approaches.

Feature MapActivity MapView

Embeddable directly into your own Layout? No (can only set map display) Yes

User-controlled navigation? Yes Yes

Navigation via code? (i.e. scroll, zoom, etc. from your application code) No Yes

Can fire events into your own code? No Yes

The advantage of using the MapView over the Activity is that it gives you tight integration with your own layout; for instance,

you can wrap custom controls around it, or implement fancy input mechanisms (such as using a tilt-sensor to scroll the Map

based on how the user tilts the device). The disadvantage of using the MapView is that it requires more code to set up and

use; if you simply wish to display a Google Map with the standard UI, it will be much easier to use the Activity.

Applications will frequently need to communicate between devices. For instance, you might wish to send messages back

and forth between two devices, to implement an interactive game of checkers. Or, you might develop a social application

where you want to send a message to a buddy.

One way to do this is to simply send an SMS message to the other phone. It's possible to receive notifications via an

IntentReceiver of incoming SMS messages, inspect them to see if they contain data intended for your application, and then

consume the message, preventing other applications (and the user) from ever seeing it directly. This works well, but it has

two major down-sides: SMS messages can take several minutes to deliver, and they typically cost users money to send and

receive. If you built an online game using SMS message-passing, it might very well be both slow and frustrating, and very

expensive to your users.

As an alternative, Google provides an API that uses the XMPP protocol to pass messages. XMPP includes presence

notification, meaning that it provides a convenient way for phones to notify each other when they are online and available for

message-passing. It also provides a programmatic model similar to SMS-based message-passing, in that the sender calls a

method on a Service to send a message, and the receiver is notified via a broadcast Intent (which it can fetch via an

IntentReceiver). However, because XMPP is a persistent socket connection, the response time is much faster than SMS,

Google APIs and Services in Android

MapView

P2P Services Using XMPP

©2007 Google - Code Home - Site Terms of Service - Privacy Policy - Site Directory

allowing for a more fluid user experience.

The system currently maintains a single XMPP connection to the server, and all XMPP traffic — including both standard

XMPP instant messages, and this P2P message-passing system — is carried on the same connection.

109Compiled by fastop 2007-2 http://fastoponandroid.googlepages.com