Developer How-To
Examples and Tips for Android Development
Install Android SDK, Eclipse, and Emulator (AVDs)
Mar 22nd
Android is a large and fast-growing segment of the mobile phone market. With potentially 350,000 users activating a new Android phone every day and multiple Android App Stores popping up (Google’s Android Market was recently revamped, and now other markets are coming online, like Amazon’s Android App Store), now is a great time to jump into Android development.
This walk-through will get you started installing the Android Software Development Kit (Android SDK), installing and configuring the Eclipse IDE for Android development, and choosing and installing Android Virtual Devices (AVDs) to emulate the Android environment right on your local computer. After following these steps, you will be ready to create your first Android application!
1. Download the Android Software Development Kit (SDK)
http://developer.android.com/sdk/index.html
The very first step is to download the Android Software Development Kit (SDK) that will let you emulate Android on your local computer. It is not too large (only ~30MB, compared to the monolithic XCode/iPhone SDK, which is almost 4GB!).
From the Android SDK Download Page, make sure to choose the version that is correct for your operating system.
After your Android SDK download is complete, unzip and move the new folder to a permanent location (*not* your downloads directory). I use a folder in my home directory (~/Android/android-sdk-mac_x86/) but you can move it anywhere you would like. There is no wrong location. Wherever you choose will hereby known as $ANDROID for future reference.
2. Download Eclipse IDE for Java Developers
http://www.eclipse.org/downloads/
When I develop for Android, I choose to use Eclipse as my Integrated Development Environment (IDE). Eclipse can be suitably adapted for Android development since you can get plugins to help with creating your Android project, launching your Android emulator, and preparing your Android application for the Android Market. It is not an ideal IDE, but the pros outweigh the cons for Android Development.
From the Eclipse Downloads Page, choose the “Eclipse IDE for Java Developers. Make sure you are getting the correct version for your operating system. Eclipse is fairly large (~100MB) but still a lot smaller than the 4GB XCode for the iPhone!
After your Eclipse IDE download is complete, unzip and move to a permanent folder. I use the applications directory in my home folder (~/Applications/).
For OSX users: we will want to have access to Eclipse.app from within our Applications folder. To do this:
- Make an alias of the Eclipse.app file (CTRL-Click then “Make Alias”)
- Move the alias into root applications folder (/Applications/) so that it shows up next to your other applications
Now you can use Eclipse just like any other application, including adding it to your dock. I do this with all of programs that I download that do not have installers (i.e., they are just .app files). This may not be a necessary step (I am fairly new to OSX), so please let me know if there is a better way!
3. Install the Android Development Tools (ADT) plugin for Eclipse
http://developer.android.com/sdk/eclipse-adt.html#downloading
Next, we will use Eclipse to install the Android Development Tools (ADT) using Eclipse’s built-in plug-in system. From within Eclipse:
- Choose “Help” > “Install New Software….”
- Click the “Add…” button and create a new entry:
- Name: “Android ADT” (this space is for your own personal use, so name it whatever you want)
- Location: “https://dl-ssl.google.com/android/eclipse/” (try just http:// if the https:// does not work for you)
- Check all the boxes to install all the tools
- Just keep clicking “I agree”, “Next”, “Yes”, etc. until it asks you to restart
- Go ahead and restart Eclipse when prompted to
4. Connect Android SDK with Eclipse IDE
This next step connects the Android SDK from Step #1 to the Eclipse IDE from Step #2. In Step #3, you should have restarted Eclipse. If you have not done so, do that now. From within Eclipse:
- Click on the “Eclipse” menu (next to the apple logo for OSX) and choose “Preferences”
- Click on “Android” heading in the menu-tree to open our Android Eclipse preferences
- Click the “Browse…” button to the right of the ”SDK Location” box
- Enter the location of your Android SDK (the $ANDROID path from Step #1)
5. (Optional) Additional Android/Eclipse Config
While we are in the Android section of our Eclipse preferences, let’s change a few more things. These steps are entirely optional. For these additional preferences, we need to expand the menu-tree under the “Android” heading:
- Click on the triangle next to the “Android” heading in the preferences tree to expand our options
- Click on the “DDMS” sub-heading and change the “Logging Level” settings to “Verbose” so that we see everything that goes on while developing
- In the “Usage Stats” sub-heading, click the checkbox to allow Google to know how we are using the SDK (seems fair enough, right?)
6. Decide Which Android Platforms You Will Support
http://developer.android.com/resources/dashboard/platform-versions.html
This graph will help you decide which ones are relevant and worth your time. I recommend checking the Android Platform Versions Graph every month or so to see how rapidly it changes! When I first found this graph less than a year ago, Android 1.5 and Android 1.6 together represented ~50% of the graph. Today, they are only ~8%. For me, this dramatic change in Android 1.5/1.6 deployment means that my efforts will be better spent focusing on Android 2.1+. For you, it may be worth it to support 1.5/1.6 for those 8% of users. Only you can make that decision.
When deciding, consider that you will need to test, debug, and provide customer support for every version of Android that you support, and for each individual device that runs those versions! For example, deciding to support 2.1 means that there are a whole host of different hardware devices that you may receive feedback regarding; whereas supporting 2.3.3 (for right now) only means the Nexus One and the Nexus S. Just keep that in mind while deciding.
From a resources standpoint, not only do you need to test and support each version that you plan to release for, but you also need to have those Android SDKs and Android Emulators on your machine (which takes up space; which, on my smaller SSD, is a finite resource). It may not be an issue for your, but it is just yet another thing to keep in mind.
Finally, no matter which versions you choose to support right now, make sure to check the Android Platform Versions Graph every month or so to see how it is changing, and to adjust accordingly. This will let you know when you can stop supporting older versions of Android and, most importantly, will let you know when you need to start supporting newer versions of Android as they grow and gain traction.
7. Install Android SDK Components
http://developer.android.com/sdk/adding-components.html
Android is packaged in such a way that the base Android SDK (downloaded in Step #1) is distinct and separate from each API version of the Android SDK. This means that for each version we want to support (from Step #6), we need to download a separate Android SDK for that version. This can be very annoying when installing (notice how many steps we have done by now), but in the long-run is a very beneficial design for us Android Developers. As new API versions are added and old API versions are phased out, we can install/uninstall the APIs as compnents, rather than a single huge download like XCode is for iPhone (4GB! I just can’t get over that! Who has a 4GB download for a minor version change?!)
We need to download the Software Development Kits (SDKs) for the Android versions that we want to support. To do this, we can use the Eclipse IDE + Android ADT that we installed in Step #3. From within Eclipse:
- Click on “Window” then “Android SDK and AVD Manager”
- In “Available packages”, select the platforms you want to support. You can either choose all, or pick-and-choose what you want to develop for. For example, 2.1, 2.2, and 2.3.3 are all I care about, so I am using API 7, 8, and 10. In the “Android Repository” package, I checked the boxes next to:
- Android SDK Platform-tools, revision 3
- SDK Platform Android 2.3.3, API 10, revision 1
- SDK Platform Android 2.2, API 8, revision 1
- SDK Platform Android 2.1, API 7, revision 1
- Samples for SDK API 10, revision 1
- Samples for SDK API 8, revision 1
- Samples for SDK API 7, revision 1
- Android Compatibility package, revision 1
- In the “Third party Add-ons”, decide what you are interested in. If you are going to be using Google Maps (or anything Google beyond Android), you want to install their APIs. If you want their licensing / billing packages, get those too. I checked the boxes next to:
- Google APIs by Google Inc., Android API 10, revision 1
- Google APIs by Google Inc., Android API 8, revision 1
- Google APIs by Google Inc., Android API 9, revision 1
- Google Market Licensing package, revision 1
- Google Market Billing package, revision 1
- Choose “Install Selected”, then the “Accept All” radio button, then “Install”. This may take a while. If it seems like your download has paused, check for any confirmation dialogs that you need to click “Accept” to. These can sometimes be hiding in the background.
8. Create Your Android Virtual Devices (AVDs)
http://developer.android.com/guide/practices/screens_support.html#testing
Last but not least, we need to create Android Virtual Devices (AVDs) that will be our Android Emulators for running and testing our Android applications on our local computer. In the same “Android SDK and AVD Manager” from Step #7, choose “Virtual Devices” on the left and create “New…” ones. I like to create AVDs to represent different Android versions that I want to test, as well as different hardware specs and screen densities my users are likely to be using.
The main idea is to test different versions of the Android API, as well as different screen resolutions and densities. I tend to pair older versions of Android (most likely running on older hardware) with lower screen densities, and new versions of Android (most likely running on newer hardware) with better screen resolutions.
Final Thoughts
These 8 Steps should be enough to get you up and running on your local computer, and ready to create and test your first Android application. There are plenty more things to cover regarding testing and packaging of your application, but this is at least a start for now. If you have any questions, issues, or suggestions, please leave a comment below!
Resources NotFoundException
May 27th
The below Resources$NotFoundException log results from user error and is easily fixed.
Uncaught handler: thread main exiting due to uncaught exception android.content.res.Resources$NotFoundException: String resource ID #0x1 at android.content.res.Resources.getText(Resources.java:205) at android.widget.TextView.setText(TextView.java:2809)
I get this error when I am trying to set a View’s text using an integer value like:
view.setText(iSomeInteger) // This is incorrect !
Instead, to set the text of a view using an integer, you need to do:
view.setText(Integer.toString(iSomeInteger)) // setText with an int
The problem is that setText(int) is reserved for string resource ids, like:
view.setText(R.string.someStringId) // setText with a string resource id
The last part of this puzzle is when you want to concatenate a string resource with other text, you need to use getString(int). Otherwise you will end up with the string resource id (not the string itself) as part of your new text:
// concatenate a string with a string resource
view.setText("Some Text: " + getString(R.string.someStringId))
Click & Long-Press Event Listeners in a ListActivity
Apr 22nd
Listening for and handling click and long-press (a.k.a. long-click) events in an Android ListActivity is a a simple matter of defining setOnItemClickListener and setOnItemLongClickListener delegate methods in the ListView.
For individual list items to be clickable, you will want to let the ListActivity’s ListView handle the onItemClick and onItemLongClick events that Android fires when a user interacts with your application.
First, get your ListView from your ListActivity. The ListView will handle the click and long press Android events for your ListActivity.
ListView lv = getListView();
Next, provide a method to handle the click when users press and release a list item in the ListView.
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
onListItemClick(v,pos,id);
}
});
Define your method to handle the onItemClick. This accepts a View which is the individual UI element that was clicked. This View corresponds to your layout that you set in your Adapter for your ListActivity. The position corresponds to which list item was clicked in the ListView (starting with a 1-index).
protected void onListItemClick(View v, int pos, long id) {
Log.i(TAG, "onListItemClick id=" + id);
}
Handling long press events is essentially the same as handling clicks except that you return a boolean which specifies whether Android should continue to propagate the click event.
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
return onLongListItemClick(v,pos,id);
}
});
If your long-click method returns true then you are telling Android that you handled the event and nobody else should know about the long-press. If your method returns false, Android will still call other handlers such as your onItemClick handler. Long-press events in Android typically do not perform the same action as a regular press, so it may be best to return true to stop event propagation.
protected boolean onLongListItemClick(View v, int pos, long id) {
Log.i(TAG, "onLongListItemClick id=" + id);
return true;
}
Outside This Scope
This is just the beginning for handling clicks within Android ListActivities and ListViews. Below are topics not covered within the scope of this post.
- Performing actions within your onListItemClick such as starting a new Activity and sending information about the item that was clicked
- Creating a custom context menu during your onLongListItemClick method
- In Android SDK 1.6+, there is an easier way to attach click listeners to Views
- You can set individual click listeners for Views within each list item to perform different actions depending on where you click within the list item
Resources
I did not come up with this out of my own brainz. I have only compiled and annotated information I have found online. The following resources may provide additional, useful information.
- Android Developers Google Group – Long click on list activity item
- 7touch Group Blog – Android List Item Click Listener (scroll down to the “Easier click listeners” section)
Vibration Examples for Android Phone Development
Mar 27th
Making Android phones vibrate is a good way to provide haptic feedback to users or to interact with users even when phone volume is low. This can ensure a better user experience and therefore increase the perceived integrity of your Android application.
The Vibrator Documentation describes the interface for making an Android phone vibrate. With this interface, you can cause an Android phone to vibrate in one of the following ways:
- Vibrate for a given length of time
- Vibrate in a given pattern
- Vibrate repeatedly until cancelled
Below are examples of these three vibrating methods.
IMPORTANT: First, Grant Vibration Permissions
Before you start adding the code necessary to cause your application to vibrate, you must first notify Android that your application expects to have permission to use the Vibrator. If you do not do this, you will receive a Force Close. Nobody likes encountering a Force Close; Do not forget this important first step!
Add the uses-permission line to your Manifest.xml file, outside of the block.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="..."> <uses-permission android:name="android.permission.VIBRATE"/> <application android:label="..."> ... </application> </manifest>
Example: Vibrate for a Given Length of Time
This example is useful when a user touches your application and you would like to provide haptic feedback. This is the simplest method of vibration. I like 50 milliseconds as a good single-touch-feedback vibrate. You can experiment with different lengths (on your physical phone) to decide how long to make your vibration.
CUIDADO: This code must be called with a reference to a Context
// Get instance of Vibrator from current Context Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); // Vibrate for 300 milliseconds v.vibrate(300);
Example: Vibrate in a Given Pattern
This method of vibration is useful when you need to provide a user with a one-time notification, such as receiving a text message. In this example, I have created a one-time vibration notification in the Morse Code SOS pattern.
CUIDADO: This code must be called with a reference to a Context
// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// This example will cause the phone to vibrate "SOS" in Morse Code
// In Morse Code, "s" = "dot-dot-dot", "o" = "dash-dash-dash"
// There are pauses to separate dots/dashes, letters, and words
// The following numbers represent millisecond lengths
int dot = 200; // Length of a Morse Code "dot" in milliseconds
int dash = 500; // Length of a Morse Code "dash" in milliseconds
int short_gap = 200; // Length of Gap Between dots/dashes
int medium_gap = 500; // Length of Gap Between Letters
int long_gap = 1000; // Length of Gap Between Words
long[] pattern = {
0, // Start immediately
dot, short_gap, dot, short_gap, dot, // s
medium_gap,
dash, short_gap, dash, short_gap, dash, // o
medium_gap,
dot, short_gap, dot, short_gap, dot, // s
long_gap
};
// Only perform this pattern one time (-1 means "do not repeat")
v.vibrate(pattern, -1);
Example: Vibrate Repeatedly Until Cancelled
This method of vibration is useful when you need to notify the user of something that requires more immediate action, such as an incoming phone call. You can repeat a given pattern until the Vibrator is cancelled, either by the system or manually by your Android application.
CUIDADO: The below example will cease vibrating when the screen times out.
CUIDADO: This code must be called with a reference to a Context
// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Start immediately
// Vibrate for 200 milliseconds
// Sleep for 500 milliseconds
long[] pattern = { 0, 200, 500 };
// The "0" means to repeat the pattern starting at the beginning
// CUIDADO: If you start at the wrong index (e.g., 1) then your pattern will be off --
// You will vibrate for your pause times and pause for your vibrate times !
v.vibrate(pattern, 0);
In another part of your code, you can handle turning off the vibrator as shown below:
// Stop the Vibrator in the middle of whatever it is doing // CUIDADO: Do *not* do this immediately after calling .vibrate(). // Otherwise, it may not have time to even begin vibrating! v.cancel();
Notes
This article only covers a subset of issues related to Vibration on the Android platform but it should provide a good starting point. Below are a few things I have noticed but did not cover in this write-up. I would appreciate comments about these, if you have any:
- From what I have read, there is unfortunately no way of changing the vibration intensity.
- I did not research or discuss how to make phone vibrate despite the screen timeout.
- I have not seen the Vibrator log its activities in LogCat which makes it difficult to tweak vibration.
- As a result, I test vibration directly on my phone which requires exporting and installing my application on my physical phone. Tedious at best.