Getting Started with Android

From Cs160-sp08

Jump to: navigation, search

Contents

Important Notice - Updated Android SDK released

As of February 13th, Google has released a new version of the Android SDK. Since we haven't started working in Android much yet and the new version of the SDK packs a lot of bug fixes and new features, you should plan on upgrading. If you're using the lab machines or have already set up your own machine you'll can upgrade the SDK using the instructions here.

Note that you'll have uninstall and reinstall the Android Eclipse plugins rather than just updating them. Also note that when you upgrade you'll need to manually update any old applications you've written and would like to use with the new SDK. These changes primarily affect the Android Manifest and Layout files but other parts of the SDK have changed as well. See http://code.google.com/android/migrating/m3-to-m5/m5-api-changes.html for more information.

It appears that the basic tutorials provided by Google have been updated to reflect the new version, but tutorials elsewhere may not be updated yet, so be aware of this.

Installing In the CS160 Lab (330 Soda)

Eclipse 3.3 and the Android SDK should already be loaded onto the machines in 330 Soda. However since the packages were installed, Google has released a more recent version of the Android SDK. Therefore, once you've set up the current installation as described below, we recommend you download and install the most recent version of the SDK. Instructions for installing the latest version of Android are available here.

If you want to have your own unique Eclipse installation that's consistent across all the machines and not shared with everyone else, you'll need to take a couple of steps:

1) If you haven't already done so in the past, you can log onto one of the EECS Unix servers (Quasar, Pulsar, Cory, etc.) and create a personal cross-platform temp directory that will provide you with space to put a copy of Eclipse. The readme (README.txt) in the /home/tmp/ directory provides instructions on how to do this. These temp directories don't have any size quotas, but they ARE NOT BACKED UP, so it's a great place to put things like the Eclipse install but probably not a good place to leave your code.

2) Connect to your new temp directory (\\ping\tmp\{yourname}) directly or mount it as a network drive ("Tools > Map Network Drive" in Windows Explorer).

3) COPY Eclipse 3.3 and the Android SDK from the common location on the lab machines to your new temp directory. Each lab machine should have a copy of Eclipse:

  • C:/TEMP/eclipse

If one of the lab machines doesn't have these files, it means someone else probably moved them off or deleted them. Try another machine or tell William Chen (across the hall in 333 Soda) and he can reinstall them. Alternately you can download the latest version from www.eclipse.org

4) Open YOUR copy of Eclipse and select a workspace. This is where all of your project source will go. Ideally you'll choose a workspace directory in your home directory on one of the departmental servers and NOT on the local machine.

5) Download and install the most recent version of the Android SDK. Because the new Android plugin for Eclipse is different from the one we already had installed in the copy of Eclipse that's on the machines, you'll need to actually remove the old Android plugin from Eclipse and load the new one. See instructions here.

Installing on a Personal Machine

1) If you don't already have it download and install Eclipse 3.3 (3.2 Should also work)

Download a copy of Eclipse from http://www.eclipse.org/downloads/ (Eclipse IDE for Java Developers)

You should more or less be able to just unzip the folder to a suitable location and then run eclipse.exe

2) Download and install the Android SDK

Download the SDK from http://code.google.com/android/download.html

Extract the zip file to the location of your choice (wherever you usually keep developer code) and continue to the next step.

3) Install the Android Eclipse Plugin (instructions copied from http://code.google.com/android/intro/installing.html#installingplugin)

  • 1.Start Eclipse, then select Help > Software Updates > Find and Install....
  • 2.In the dialog that appears, select Search for new features to install and press Next.
  • 3.Press New Remote Site.
  • 4.In the resulting dialog box, enter a name for the remote site (e.g. Android Plugin) and enter this as its URL: https://dl-ssl.google.com/android/eclipse/
  • 5.You should now see the new site added to the search list (and checked). Press Finish.
  • 6.In the subsequent Search Results dialog box, select the checkbox for Android Plugin > Developer Tools > Android Development Tools and press Next.
  • 7.Read the license agreement and then select Accept terms of the license agreement, if appropriate. Press Next.
  • 8.Press Finish.
  • 9.The ADT plugin is not signed; you can accept the installation anyway by pressing Install All.
  • 10.Restart Eclipse.
  • 11.After restart, update your Eclipse preferences to point to the SDK directory:
    • a. Select Window > Preferences... to open the Preferences panel. (Mac OS X: Eclipse > Prferences)
    • b. Select Android from the left panel.
    • c. For the SDK Location in the main panel, press Browse... and locate the SDK directory.
    • d. Press Apply, then OK


Getting Started in Android

1) Creating or importing a new Android project in Eclipse (instructions from http://code.google.com/android/intro/installing.html#developingwitheclipse)

The next steps will guide you through the process of creating a new application, but if you want to jump straight in and start coding or load one of the sample projects, do the following:

  • 1. Select File > New > Project
  • 2. Select Android > Android Project.
  • 3. Select the contents for the project:
    • Select Create new project in workspace to start a project for new code.
      • Project Name - The name of your Eclipse project and source directories
      • Package Name - The package name. Our convention is "edu.berkeley.edu.cs160.{your name or group name}.{project name}"
      • Activity Name - The name of the main Activity that will be launched to start your application. An activity with this name will automatically be created in the new project.
      • Application Name - The plaintext name of your project. This is what the application will be show up as in the applications folder on an Android phone.
    • Select Create project from existing source to load an existing project. All sample projects are loaded this way.

2) Try the Simplest HelloWorld

at: http://code.google.com/android/intro/hello-android.html

This tutorial gives step-by-step instructions for creating a very simple hello world with an XML-defined UI.

Note: Resources, including images, text files, XML data, and user interfaces defined using the XML-based layout files can be placed in the /res directory. These resources are then accessed in the Java code using the helper class R, which is automatically generated and appears as R.java in the application source.


3) Change the Emulator Skin We'll be favoring the variation of the Android emulator skin that contains a QWERTY keyboard. You can change the emulator skin from the Run dialog for any android application before you launch it. In the Emulator tab, just change Screen Size to 'QVGA-L'. If you're launching the emulator from the command line 'emulator -skin QVGA-L' should also do the trick.


4) Work Through a More Advanced Android Tutorial

at: http://code.google.com/android/intro/tutorial.html

This tutorial covers more advanced UI design, using the SQLite database to store data on the device, passing data between activities, and correctly handling the application lifecycle.


5) Other Tutorial & Example Applications

A whole bunch of tutorials produced by outside developers have also popped up on the web: http://wiki.droiddocs.net/Tutorials is a good place to start


Building Blocks

Activities, Intents, Services, Content Providers and other Android building blocks (for more information see http://code.google.com/android/intro/anatomy.html and http://code.google.com/android/devel/building-blocks.html)

Activity - usually a single screen used to accomplish a task. An application usually consists of one or more activities. When you create an application you'll create one activity that serves as the entry point for the app. Its onCreate() method is effectively the main() method of the application since it is the first method that will be called when your program is launched.

Intent - used to move from activity to activity and obtain data. An intent is essentially an abstract request from an application for an action to be performed by some other activity or service. Intents have two important pieces of information which define them: 1. An action - VIEW_ACTION, EDIT_ACTION, MAIN_ACTION, etc. 2. Data to operate on. For example, an activity that wanted to retrieve a contact name from the address book might issue an intent with the PICK_ACTION action and content://contacts/ as the data pair. A contact list activity can then respond to this intent and launch, allowing the user to select a contact, at which point the contact list disappears and the user returns to the original activity. This allows a lot of flexibility in application design, since different components of the system can (e.g. the contact list) can be replaced, altered, or customized and all applications that use them will benefit. Activities advertise which intents they can handle by setting up Intent Filters.

Service - These run in the background and provide functionality even when an activity isn't running. Other components can bind in and execute methods on a service object via remote procedure calls.

ContentProviders - provide access to data on the device. Applications can expose data to others using them.


Moving from one Activity to Another

You can move within activities in your application by calling the StartSubActivity() method. For example, if you need to allow users to look at their contacts within an email application, you can launch a second activity that shows a contact list. The cool thing about this is that while you can specify a specific Activity that you want to watch, you don't necessarily have to. Instead you can call StartSubActivity() with an Intent that specifies what you want to do, and if an activity with intent filters that match your already exists on the system, it will be launched instead. This means that if you want to show a list of contacts you can easily launch the master contact list activity for the phone (or some other variation of the contact list created by another developer) without even knowing what that Activity is.


  • To start a specific Activity:

Use StartSubActivity(new Intent(Context packageContext, Class cls), int requestCode) where packageContext is the current Context (usually 'this'), cls is the class of the Activity you want to launch (i.e. MyActivity.class) and requestCode is an integer value of your choosing (probably a predefined constant) that you can use to identify the sub activity when it calls onActivityResult.


  • To start a task-defined Activity:

Use StartSubActivity with an Intent that specifies the desired action, rather than a specific class. See http://code.google.com/android/reference/android/content/Intent.html

When any sub-activity finishes, the onActivityResult method in the parent Activity is triggered. To execute additional handling code at this time, override the onActivityResult method of the calling Activity.


Bundles

For the API entry on the Bundle class, look here http://code.google.com/android/reference/android/os/Bundle.html

Bundles are Android's way of maintaining and passing program state. The system is constructed around the assumption that any program (characterized by a collection of activities) may be preempted at any time, and if the system resources are low, may be subsequently killed. To handle this difficulty, a Bundle called an icicle is saved whenever the activity is preempted.

Like with a hash table or dictionary, items added to the Bundle are given a key which is later used to retrieve the data (using data-type specific methods like getCharacter(String key) and getParcelable(String key)). When you are creating activities, be sure to save any important state information into the icicle given to onFreeze so that you can restore your program in onCreate if it is killed while suspended.


The two most common Bundles with which you will interact initially are:

  • icicle bundle - holds key/value pairs that were stored when the Activity was frozen previously
  • extras bundle - holds key/value pairs that were passed from the parent Activity

Activity Lifecycle

Like HTML webpages, Android provides functionality for setting up and tearing down. HTML provides the ability to respond to events through triggers like onLoad and onUnload. Android provides eight such methods, each to respond to a very specific situation. For all the details see this page: http://code.google.com/android/reference/android/app/Activity.html


This image from Google's official site gives a good overview

Image:activity_lifecycle.png

onCreate() - called when an activity is launched. If the activity state was previously saved in an icicle (by onFreeze()), and the activity was subsequently killed to free memory, this will receive the saved icicle bundle.

onFreeze() - called when an activity is being paused and another one is resuming to interact with the user. The current activity may be killed before it resumes, so this method saves an icicle bundle.

onPause() - called any time an activity is suspended (including when an explicit finish() call is made). This happens any time another activity is brought to the foreground instead. Best practice is to release all possible resources for use by other processes here. For example, set local variables to null so their targets can be garbage collected.

onResume() - called any time an activity is entered or re-entered, and is about to begin interacting with the user.

onStart()/onStop() - called when the activity becomes visible to the user, or stops being visible to the user.


Some instances of when these are called

  • Entering an activity normally triggers: onCreate(), onResume()
  • Exiting an activity with a finish() call triggers: onPause()
  • Using the Back button in an Activity calls: onPause()
  • Using the Home or End buttons in an Activity calls: onFreeze(), onPause()
  • Entering an Activity left using Home or End triggers: onResume()

Resources and XML UI

Using the R class to access resources

The directory structure of an Android application contains a special directory named res that is used for holding resources (non-code files) that you'll use in your applications.

The res folder has three important sub-directories:

  • drawables - holds JPG and PNG image files that you want to include in your application
  • layout - holds XML-based representations of the GUI layouts you'll create for your application
  • values - holds XML-based representations of a number of different types of objects including text strings and arrays you want to include in the application, colors and UI styles you want to predefine, etc.

The cool thing about using this directory structure is that Android automatically provides a helper object (called R) which allows you to access any supported resources you've included in the directory. For example, to access a layout you've defined, use:

R.layout.layout_name

where layout_name is the name of an xml file layout_name.xml included in the layout folder. Using the autocomplete feature in Eclipse can really help you here, since it can show you exactly what resources are currently available through the R object.

Even though the R.java file representing the R object is placed in your source directory, you shouldn't edit it. It's constantly being updated every time the directory changes, so any changes you make will be lost.

For more information see the summary on droiddocs: http://wiki.droiddocs.net/Resources_and_Internationalization


XML UI

A simple sample UI
A simple sample UI

Android uses an XML based markup language to define user interface layouts, in a way that's similar to UIML. XML is used to create flexible interfaces which can then be modified and wired up in the Java code. Mozilla's XUL, Windows Presentation Foundation XAML, and Macromedia Flex's MXML (and to some extent even SVG) all operate similarly.

Each node in the XML tree corresponds to a screen object or layout container that will appear in the rendered interface.

For example, the XML below defines the interface seen here.

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout android:id="@+id/myAbsoluteLayout" 
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" 
  android:background="@drawable/black" 
  xmlns:android="http://schemas.android.com/apk/res/android">
 <Spinner android:id="@+id/mySpinner" 
   android:layout_width="fill_parent" 
   android:layout_height="wrap_content" 
   android:layout_x="0px" 
   android:layout_y="82px" >
 </Spinner>
 <Button id="@+id/myButton" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:background="@drawable/darkgray" 
   android:text="Ok"    
   android:layout_x="80px" 
   android:layout_y="122px" >
 </Button>
</AbsoluteLayout> 

Notice how the outermost XML node is a layout container, that contains the spinner widget and button. This AbsoluteLayout container allows UI elements to be positioned at specific locations within it. This is done using the android:layout_x and android:layout_y attributes on the widgets. The height and width of the components is set using the android:layout_height and android:layout_width tags respectively. Notice that you these either use absolute pixel values (e.g. "50px") or one of several specific constants which allow you to fit the object to its parent or its content. Using "fill_parent" causes an object to expand as much as possible - like the width of the spinner in the example. Using "wrap_content" causes the object to be sized just large enough to encompass its content.

The id attribute allows you to set a name for each component that you can use to access it in your application. For example, the id tag in the code sets the spinner's id to "@+id/mySpinner". Once this interface has been loaded, you can get a reference to this specific spinner by using the findViewById method. For example, to get a reference to the spinner in the code below:

Spinner spinner = (Spinner)findViewById(R.id.mySpinner);

A lot of common UI components, including buttons, textboxes, listboxes, spinners, image galleries, autocomplete text fields, and more are provided by Android. Look at the android.widget and android.view packages for a more complete list. These can also be extended or modified by subclassing them (http://code.google.com/android/toolbox/custom-components.html).

A number of layouts are also provided. A few of the more useful ones are:

  • AbsoluteLayout - children can be positioned at absolute x, y coordinate positions and may overlap.
  • FrameLayout - allows children to be attached to its edges.
  • LinearLayout - children are positioned one after another either vertically or horizontally and do not overlap.
  • TableLayout - used to create more elaborate row/column positionings.

(http://code.google.com/android/devel/implementing-ui.html) provides an introduction to layout. For more layout components, see (http://code.google.com/android/devel/ui/layout.html).


Nesting XML UIs

When constructing larger, more complicated UIs, you may want to nest multiple XML UI layouts. (For example, nesting a control bar defined in one XML file at the top of an interface designed in another.) You can load additional layouts without replacing the UI already loaded in the Activity by using a ViewInflate object obtained from the system. The code below places an tool bar defined in an XML file called mytoolbar.xml inside a RelativeLayout object called toolbarholder located in the Activity's currently loaded layout. Note that the layout parameters for the object being added must match the type of layout it's being added to.

	ViewInflate vi = (ViewInflate)getSystemService(Context.INFLATE_SERVICE);
	View myView = vi.inflate(R.layout.mytoolbar, null, null);
	myView.setLayoutParams(new RelativeLayout.LayoutParams(200,20));
	RelativeLayout myLayout = (RelativeLayout)findViewById(R.id.toolbarholder);
	myLayout.addView(myView);

Tools

- Android Eclipse Views - The Android Eclipse plugin adds a number of new Eclipse views that you can use for debugging applications and tweaking the emulator. To turn these on in Eclipse go to: Window > Show View > Other... Then, under 'Android' select one or more of the views and hit 'OK'. Devices - Provides a list of running emulators and lets you screen capture from and reset them. Emulator Control - Lets you simulate incoming voice and SMS messages and simulate different telephony states (roaming, no signal, latency, etc.) in the current emulator. File Explorer - Lets you browse the directory structure on the emulated device. Heap, Processes, Threads - Provide access to lower-level memory and processing information from the emulated device. LogCat - Log viewer from the device. Can be filtered to five different priority levels (two more filtering levels are available in ADB).

  • V — Verbose (lowest priority)
  • D — Debug
  • I — Info
  • W — Warning
  • E — Error
  • F — Fatal
  • S — Silent (highest priority, on which nothing is ever printed)

You can print error messages and other debug information (much like System.out.println() in Java) to the Android log using the static android.util.Log class. Which of Log's methods you call depends on what priority you want the output to be displayed. The options are:

  • Log.v() - for verbose
  • Log.d() - for debug
  • Log.i() - for info
  • Log.w() - for warnings
  • Log.e() - for errors

- Emulator Console - Some real-time functions of the emulator, such as simulating incoming phone calls and SMS messages, can also be accessed using the emulator console. You can access the emulator console using telnet to connect to a port on the local machine (usually localhost 5554) which corresponds to the emulator. (See http://code.google.com/android/reference/emulator.html#console for more information.)

- Android Debug Bridge (ADB) - Provides greater access to other emulator functions, including handling port-forwarding, copy files to/from an emulated device and installing applications on the emulator. (See http://code.google.com/android/reference/adb.html)


Notice: due to the changes in the SDK, the following third-party applications will not work. DroidDraw will still function, but the XML that it generates will need to be corrected to allow it to work with the new standards.


- DroidDraw (www.droiddraw.org) - An unofficial, unsupported GUI builder for Android. Allows you to generate Android UI definitions visually rather than actually writing XML code. It may or may not be reliable.

- OpenIntents SensorSimulator - A 3rd party plugin for the Android emulator that allows you to simulate accelerometer, compass, orientation, and temperature sensors. It may also be possible to use it to pipe data from an external accelerometer into the emulator.

Useful libraries to check out

android.location & com.google.maps (http://code.google.com/android/toolbox/apis/lbs.html)

android.media (http://code.google.com/android/toolbox/apis/media.html)

android.opengl (2D and 3D graphics)

com.google.android.xmppService (message passing support.)

...

Resources

Androidology Videos - A set of overview videos from the Android development team.

The official Android site.

The official Android bug tracker / issue list.

wiki.droiddocs.net - Unofficial Android Wiki

  • DroidDocs list of known bugs - Google didn't initially have a publicly accessible bug tracker, so this used to be the best place to report and assess bugs.

http://www.android-freeware.org/ - A growing list of applications under development.


Forums

http://groups.google.com/group/android-beginners/

http://groups.google.com/group/android-developers

http://www.anddev.org/



[add comment]
Personal tools