Android, Interesting

A hail of mail with Hailgun

The Hailgun library

Very recently I was writing a shared service in Haskell and we realised that we would need to integrate with an email service provider. After a little bit of research I concluded that Mailgun was a great service for developers to send their emails so I looked for Mailgun integration libraries that looked like they were being groomed to be “the” Mailgun library for Haskell and I was disappointed to find that the existing libraries did not seem to be very comprehensive or did not make use of type safety.

So I wrote my own library and I called it “Hailgun”. Then I uploaded it to Hackage.

I believe this library to be better because:

  • It supports simple email sending just like the existing libraries.
  • The type system is stricter, leaving less room for incorrect usage of the API. Giving you the assurance that you will be sending emails correctly.
  • There is a backlog of issues that has been roadmapped such that the library will have full Mailgun API support. It just needs time to develop it.
  • The support for the various parts of the API is being implimented and released incrementally so that people can get the benefits of the hailgun library now.
  • It comes with the hailgun-send executable out of the box. This executable can be used on the command line to send emails through the Mailgun API.
  • This library has been written in pure Haskell and does not use any FFI wrappers around another Mailgun library: the goal of this library is to work on any platform.

And this is just for version 0.1.0.0. To people that read this in the future, you should check out the library on hackage to see what it impiliments now.

Sending a test email

I’m going to explain here how to send a test email using hailgun-send so that you can quickly see that the library works and can be used to send your emails in pure Haskell code.

If you don’t have a Mailgun account and a sandbox for it then go sign up for one. Once you have created your account you should have been given an API key and have a sandbox domain name. Please create a file called ‘hailgun.send.conf’ in the current directory and make the contents of the file:

mailgun-domain    = "sandbox-mailgun-domain.com"
mailgun-api-key   = "key-thatmailgungaveme9234uoah234"

Once you have that file in place you should then be able to use hailgun-send. For example, this is one invocation that I used:

hailgun-send 
  --from 'postmaster@sandbox17bd032a44ea44f5b540470a8ab4787f.mailgun.org' 
  --to 'robertmassaioli@massaioli.com' 
  --subject 'Hailgun v0.1.0 test email' 
  -x data/email.text 
  -m data/email.html

You will notice that I provided a from and to address, an email subject and the content of the email in two files. You should create the email.text and email.html files yourself or you could simply use the ones that are avaliable in the repository. Please note that the HTML version of the email is optional but the text version is always required.

You should see something like the following email appear in your inbox:

This email was delivered via Mailgun and sent via Hailgun.
This email was delivered via Mailgun and sent via Hailgun.

Concluding Words

In short you should now be able to send emails, via Mailgun, with Haskell and the library should be improved to have more API support as time goes by. I hope this is useful to some peoplee and, if a Mailgun developer should happen to swing by this post then please feel free to review my code.

Android, Interesting

Google Calendar Subtle Duration Bug

Sometimes it is the most subtle and simple bugs that can really get under your skin and annoy you like nothing else. Recently I was dealing with data that I get sync from Google Calendear and I used RFC2445 and RFC5545 to get the specification for a ‘Duration’. Durations are important because according to the spec a VEVENT must have either a DTEND or a DURATION. Therefore I need to be able to parse durations when dealing with data that I get back from Google. The RFC’s define the duration as:

       dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)

       dur-date   = dur-day [dur-time]
       dur-time   = "T" (dur-hour / dur-minute / dur-second)
       dur-week   = 1*DIGIT "W"
       dur-hour   = 1*DIGIT "H" [dur-minute]
       dur-minute = 1*DIGIT "M" [dur-second]
       dur-second = 1*DIGIT "S"
       dur-day    = 1*DIGIT "D"

But Google Calendar does not follow that pattern…Google Calendar events have a subtle difference:

       dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)

       dur-date   = dur-day "T" [dur-time]
       dur-time   = (dur-hour / dur-minute / dur-second)
       dur-week   = 1*DIGIT "W"
       dur-hour   = 1*DIGIT "H" [dur-minute]
       dur-minute = 1*DIGIT "M" [dur-second]
       dur-second = 1*DIGIT "S"
       dur-day    = 1*DIGIT "D"

You probably did not even notice it but the ‘T’ character has moved. This caused my parser (generated with JavaCC) to fail and was an annoying problem to debug. It has also forced me to write many annoying test cases to make sure that I can easily ascertain if Google is doing the right thing in the future.

Just so that you know, this means that it generates incorrect periods. So Google Calendar generates a period that looks like this “P300S” whereas it should generate a valid period like this “PT300S”.

Android, Gamedev, Graphics

LibGDX, Blender and G3D Exporting

LibGDX is working on exporting your work from Blender or SoftImage (see the model-loaders) straight into a file format that it can handle; the file format that it has coined is G3D. Now, as far as I know the G3D file format has no specification, if you want to understand how the file format works then there is no better way than to just look straight at the implementation in the libgdx/extensions/model-loaders code (we check out this repository in step one).

This blog post explains a nice an easy way to install the Blender G3DT exporter on an OSX or Linux machine.

  1. The first step is to check out the libgdx source code which is a lovely git repository (thanks go out to the LibGDX team that recently changed it over from SVN to Git, it was a good move):
    git clone git://github.com/libgdx/libgdx.git
  2. When the source code is checked out you will need to symlink the files into your blender addons directory.
    On Mac OSX:

    cd /path/to/libgdx-read-only
    ln -s extensions/model-loaders/model-loaders/doc/blender/io_scene_g3dt /Applications/blender.app/Contents/MacOS/$(/Applications/blender.app/Contents/MacOS/blender --version | grep "^Blender" | cut -d  -f2)/scripts/addons

    On Linux:

    mkdir -p ~/.blender/$(blender --version | grep "^Blender" | cut -f2 -d  )/scripts/addons
    cd /path/to/libgdx-read-only
    ln -s extensions/model-loaders/model-loaders/doc/blender/io_scene_g3dt ~/.blender/$(blender --version | grep "^Blender" | cut -f2 -d  )/scripts/addons

    On Windows: Windows has the equivalent of Symlinks since Windows Vista. You can use the mklink command instead of the ln command to link the ‘extensions/model-loaders/model-loaders/doc/blender/io_scene_g3dt’ directory straight to your blender addons directory. That will work but unfortunately I do not have any instructions that I can guarantee will work for that; but you are pretty clever. You should be able to figure out how to use the mklink command.

  3. Now open Blender and navigate to File > User Preferences (Ctrl+Alt+U). Click on the Import-Export in the left hand side panel and then enable the G3DT Plugin by ticking the Check box next to the Import-Export: G3DT Exporter box.

    Click this simple box to activate the plugin.
    (Click on this image to get a large version of the button that you are supposed to press to activate the G3DT Exporter)

And now you are done. You can now export your blender files to the G3DT format for use with LibGDX. Not only that, but if you spot any problems with the G3DT Exporter and you manage to solve them then you can easily commit you code straight back to the larger project. You could contribute to libgdx just like that.

Android, Interesting

ClassNotFoundException when running Simple XML

The Problem

A few days ago I ran into a problem while using Simple XML in my Android codebase. Since Simple takes about 2-3 seconds to load my level files I could not perform that activity on the main UI thread; as per android design guidelines. So I threw the loading of my level into an AsyncTask as you are supposed to and thought that everything was just perfect. However, I quickly encountered a problem whereby all of my data would be written out correctly to an XML file but when I tried to read it back in I was given a ClassNotFoundException. The error looked something like this:

12-25 12:21:44.565: W/System.err(404): java.lang.ClassNotFoundException: MyCoolJavaObject in loader dalvik.system.PathClassLoader@4001b500
…more messages here…
12-25 12:21:44.575: W/System.err(404):  at org.simpleframework.xml.strategy.Loader.load(Loader.java:50)
…more messages here…
The Solution (Solving The Problem)

Whenever you push a polymorphic type into an XML file Simple XML also adds an attribute called ‘class’ and it is filled with the absolute package path of the object that was just serialised. Like this for example:

<fruit class="com.fruitseller.Apple" seeds="4">
<fruit class="com.fruitseller.Bananna"> 
    <parentTree id="4984" /> 
    <energyContent>98</energyContent> 
</fruit>

As you can see in this example, when Simple reads in these classes again it knows which constructors to use by looking up those classes in the hierarchy. Therefore, if that look-up process fails you are going to get a ClassNotFoundExeption, just like the one that I received above.

The ClassPathLoader is what is in charge of finding those classes and that is what needed to be fixed. As it turns out the new thread that the AsyncTask was running on did not have the same class path loader as the one that the UI thread of my app was using. Therefore, all I needed to do was set the class path loader in that AsyncTask before I ran any simple xml read or write functions. To do so I grabbed the one from my Application class, like this:

// The fix is this two lines
ClassLoader thisClassLoader = MyApplication.class.getClassLoader();
Thread.currentThread().setContextClassLoader(thisClassLoader);

// This Persister code
Serializer serial = new Persister();
// ...more simple code...
As you can see the fix ended up being a meager two line fix that can probably be condensed into one line. And that solved my problem completely. I hope that this helps you and if it does not feel free to ask questions in the comments.
Android, Interesting

Simple XML in Android 1.5 and Up

If you are looking for an easy way to use XML in Android then you have come to the right blog post. In this post I will take you all of the way through setting up the simple-xml library on Android so that you do not have to do so yourself and so that you can avoid the pitfalls that I did. Let us begin with a quick introduction and the requirements.

TL;DR: You can see the simple example project and run it by checking out this code example (BitBucket rocks): https://bitbucket.org/robertmassaioli/simple-xml-tutorial

About Simple and Android

I am assuming that when you have come to this blog post that you know what Android is, and that you have setup an Android Development Environment. If it just so happens that:

And then there is the Simple Framework for XML itself. Now you may not have heard of Simple before but it is a very handy annotation based package for dealing with XML that was written by Niall Gallagher and released under the LGPL Apache License (according to Niall himself in the comments below). Yes, you heard that correctly: LGPL Apache baby! For those of you that do not understand why that is great, the answer is this: you can legally use Simple in a commercial game. However, if you use the library, it might be nice you must give Niall Gallagher the proper attribution in the credits/acknowledgements section somewhere and send him a thanks for the great work; good developers love thanks (so perhaps you understand what I mean). This means that we can sell all and any of our Android apps that use the Simple framework. (Though that is not legal advice; IANAL)

Now, the question you might be having is: Why do we even want to use Android and Simple together anyway? I am glad you asked. The essential answer is that with the Simple XML library you will save heaps of developer time as your serialization and persistence code becomes an absolute breeze. You could struggle through with the provided Android libraries, or you could just use Simple and apply one annotation to a field and watch everything just magically work for you. Now the choice is yours, but I prefer the “one word, single annotation and everything just works” approach. If you do too then please read on and we’ll get started.

Download the library

Now it is time to Download Simple XML and find the appropriate JAR file to use in our project. So, lets go over to the Simple download page and download the latest version. (Though you should note that this tutorial uses Simple v2.5.2) Once that has been downloaded to your computer just unzip the package to somewhere. Inside the unzipped directory you will find a file that resided at jar/simple-xml-x.x.x.jar. This is the file that you want.

Example Android 1.5 Project

Important: In this example we use an Android 1.5 project but that means that simple should work with any Android project that is Cupcake (v1.5) or higher.

Here are the set of instructions that you should follow just to get the project skeleton created:

  1. Open Eclipse
  2. Press Ctrl+n, type in ‘Android’, select ‘Android Project’ and hit next to start creating an Android Project.
  3. In the new windows ‘Project Name’ Field put in ‘AndroidCupcakeSimpleTest’ as the project name. (Though this can be anything you like)
  4. In the ‘Build Target’ frame check the target called ‘Android 1.5’. This says that we are going to use the Android 1.5 API.
    If you do not have that option then you have not installed the Android 1.5 API and you should go do that from the ‘Android SDK and AVD’ manager.
  5. Put ‘Simple XML Test’ in the ‘Application Name’ text box.
  6. Put ‘com.simpletest.test’ in the ‘Package name’ text box.
  7. Put ‘ApplicationMain’ in the ‘Create Activity’ text box.
  8. Put ‘3’ in the ‘Min SDK Version’ text box.
  9. Click ‘Finish’ to actually create the project.

And that will give you an Android Cupcake project that you can use to test out the simple API, now to include the simple library in the project itself.

Including the External Simple Library Jar

Now we actually want to get the simple library into the Android project and that could not be easier.

  1. Make sure that you know where the simple-xml.jar file is.
  2. In Eclipse, Press Ctrl+n and make a folder in the base directory of the project called ‘libs’.
  3. Copy the simple-xml.jar file into that ‘libs’ directory.
  4. In Eclipse, click on the libs directory in the ‘Project Explorer’ and hit F5 to refresh the directory.
  5. Still in the project directory: right click on the simple-xml.jar file and, in the menu that appears, select ‘Build Path -> Add to Build Path’

Congratulations, the simple library is now included in your Android project and you can use it for great win and victory.

Advanced Android: Those of you that are more curious may know that Android can only read Dalvik bytecode; which is different to normal Java bytecode. Thus, you may be wondering, “How can the classes in the simple-xml jar file, which were compiled into different bytecode, now be made to work on a Dalvik VM? Shouldn’t we need to do something to those classes inside the jar first so that Dalvik can read them?” And that is an excellent question, with the answer being that you are completely correct; this will not ‘just work’ and something does need to do it for you. Luckily for you, this is magically done for you by the ADT plugin for Eclipse. The ADT plugin itself uses the ‘dx’ program that comes with the android SDK to compile all of the external jar classes into a single ‘classes.dex’ file that is again packaged in the final APK. You can read what is inside the ‘classes.dex’ file by extracting it from the APK and then running ‘dexdump’ on it (another program that comes with the Android SDK). Infact, if you want to see a pretty version of the dexdump then you can use an awesome program called ‘Dedexer’ written by Gabor Paller.

Writing some classes that use Simple XML

There is a comprehensive tutorial on the Simple website that teaches you how to use simple; so I am not really going to explain how this works. Look at the tutorial there to understand the details. I am just going to provide you with some code here to prove to you how easy it is to actually read this XML annotation style of code: thus convincing you that you really do want this for your own Android projects. So, without any further notes, here are the classes (please make sure that you put them in the correct packages or you will need to change the package paths):

Level.class

package com.simpletest.test.objects;

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

import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

@Root
public class Level {
	@ElementList
	public List&lt;GameObject&gt; gameObjects = new ArrayList&lt;GameObject&gt;();
}

GameObject.class

package com.simpletest.test.objects;

public interface GameObject {
	int getObjectId();
}

Apple.class

package com.simpletest.test.objects;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;

public class Apple implements GameObject {
	private final int seedCount;
	private final int id;

	public Apple(@Attribute(name = "id") int id, @Element(name = "seedCount") int seedCount) {
		super();
		this.seedCount = seedCount;
		this.id = id;
	}

	@Element(name = "seedCount")
	public int getSeedCount() {
		return this.seedCount;
	}

	@Attribute(name = "id")
	@Override
	public int getObjectId() {
		return id;
	}
}

Orange.class

package com.simpletest.test.objects;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;

public class Orange implements GameObject {
	@Element
	public double containedJuice;
	private final int id;

	public Orange(@Attribute(name = "id") int id) {
		super();
		this.id = id;
	}

	@Attribute(name = "id")
	@Override
	public int getObjectId() {
		return id;
	}
}

WriteExample.class

package com.simpletest.test;

import java.io.File;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

import android.util.Log;

import com.simpletest.test.objects.Apple;
import com.simpletest.test.objects.Level;
import com.simpletest.test.objects.Orange;

public class WriteExample {
	private final static String TAG = WriteExample.class.getCanonicalName();

	public WriteExample() {
		// Create the Dummy Level with Apples and Oranges
    	Log.i(TAG, "Create level");
    	Level level = new Level();
    	Orange orange;
    	level.gameObjects.add(new Apple(1, 10));
    	orange = new Orange(2);
    	orange.containedJuice = 20;
    	level.gameObjects.add(orange);
    	orange = new Orange(3);
    	orange.containedJuice = 100;
    	level.gameObjects.add(orange);
    	level.gameObjects.add(new Apple(4, 0));

    	// Now write the level out to a file
    	Log.i(TAG, "Write Level to file.");
    	Serializer serial = new Persister();
    	File sdcardFile = new File("/sdcard/levelout.xml");

    	try {
			serial.write(level, sdcardFile);
		} catch (Exception e) {
			// There is the possibility of error for a number of reasons. Handle this appropriately in your code
			e.printStackTrace();
		}
		Log.i(TAG, "XML Written to File: " + sdcardFile.getAbsolutePath());
	}
}

ApplicationMain.class

package com.simpletest.test;

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

public class ApplicationMain extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	new WriteExample();
    	// new ReadExample(getResources()); // Uncomment this line in the next section.
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Hopefully, this all reads easily for you, but the basic gist of it is that you annotated a bunch of levels and game objects and then you serialised a level you created into XML form and out to the ‘/sdcard/levelout.xml’ file on your Android devices SD card. If you run the program in the Android emulator then (once the line “XML Written to File” appears in the LogCat output) you can get the file like this:

$ adb pull /sdcard/levelout.xml levelout.xml

And you can look at the output like this:

$ cat levelout.xml
<level>
   <gameObjects class="java.util.ArrayList">
      <gameObject class="com.simple.test.objects.Apple" id="1">
         <seedCount>10</seedCount>
      </gameObject>
      <gameObject class="com.simple.test.objects.Orange" id="2">
         <containedJuice>20.0</containedJuice>
      </gameObject>
      <gameObject class="com.simple.test.objects.Orange" id="3">
         <containedJuice>100.0</containedJuice>
      </gameObject>
      <gameObject class="com.simple.test.objects.Apple" id="4">
         <seedCount>0</seedCount>
      </gameObject>
   </gameObjects>
</level>
$

And just look at that output, it is beautiful! And it contains all of the information that you need to know for your class to be read back in. This is big. Now, with ease, you can dump any object tree in your Android program to XML and store it on disk, or send it to a server or even just print it on the screen. Everything that you can use XML for is now at your fingertips.

Advanced Android: When you ran the previous example, if you were being particularly observant and clever, then you would have been watching the LogCat output coming out of the emulator and seen some interesting/weird warnings in the logs right when the XML was being written out. The warnings that you would have seen would have looked something like this:

I/com.simpletest.test.ApplicationMain( 1587): Write Level to file.
E/dalvikvm( 1587): Could not find method javax.xml.stream.XMLInputFactory.newInstance, referenced from method org.simpleframework.xml.stream.StreamProvider.
W/dalvikvm( 1587): VFY: unable to resolve static method 262: Ljavax/xml/stream/XMLInputFactory;.newInstance ()Ljavax/xml/stream/XMLInputFactory;
W/dalvikvm( 1587): VFY:  rejecting opcode 0x71 at 0x0003
W/dalvikvm( 1587): VFY:  rejected Lorg/simpleframework/xml/stream/StreamProvider;. ()V
W/dalvikvm( 1587): Verifier rejected class Lorg/simpleframework/xml/stream/StreamProvider;
I/global  ( 1587): Default buffer size used in BufferedWriter constructor. It would be better to be explicit if an 8k-char buffer is required.

Now these are some odd errors so, please, allow me to explain what is going on here. The first line (with “Write Level to file.”) can be ignored, it is saying that the writing process is starting and that Simple XML is about to start doing its thing. The next five lines are all from Simple XML saying that there were some Verifier errors in the Simple XML framework; in a nutshell, right here is where Simple XML works some reflection magic to see what classes it can actually use to serialize your XML. Simple XML was made to work essentially anywhere (which is why it works on Android 1.5) and this reflection code tells it what its current platform gives it to work with. It also caches the result of this reflection so you will only see these error messages appear once and then Simple XML has automatically ‘reconfigured’ itself, if you like.

The final line with the global info warning is essentially stating that the BufferedWriter constructor that Simple XML uses allocates, for itself, 8KB of buffer memory and that might be more memory than you need. This is not an issue; just the Android Developers wishing that they could break the spec and force everyone else to use the other version of the BufferedWriter constructor. As it turns out however, 8 kilobytes is a pretty good starting buffer size for dealing with XML files. For anybody that is interested you can actually see the decision made by the Android team in the comments of the Android BufferedWriter code.

Reading XML into a Class

Now that we can write XML to a file can we do the opposite and read XML from a file in? Well naturally the answer is ‘yes’. Lets start by copying the XML that we got from the last example into a raw android resource xml file called “example.xml”. This file should exist at /res/raw/example.xml in the project hierarchy. Do that right now.

Then you should add another class that does the reading:

ReadExample.class

package com.simpletest.test;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.util.Log;

import com.simpletest.test.objects.Level;

public class ReadExample {
	private final static String TAG = ReadExample.class.getCanonicalName();

	public ReadExample(Resources resources) {
		Serializer serial = new Persister();

		try {
			Level levelRead = serial.read(Level.class, resources.openRawResource(R.raw.example));
			Log.i(TAG, "Objects in Level: " + levelRead.gameObjects.size());
		} catch (NotFoundException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Important: Don’t forget to go to the ApplicationMain class and uncomment the code that calls the ReaderExample.

As you can see, the code above will read the XML file that you put in your Android project and generate an entire hierarchy of objects for you to use. It allows you to read XML from a file in an incredibly easy and intuitive way.

Things to Watch Out For

However, I should say that all was not so easy when I first tried to read in XML from a raw resource. I was getting some weird errors where it was claiming that there was nothing, or barely anything, that it could read from my provided file. What happened was that the XML file that it was trying to read in was not being read with the correct encoding (UTF-8). Therefore it was seeing what it thought was a 0 character (EOF) on the second character read and just ending the parse there erroneously. If you get a similar problem then the solution is to get the raw input stream from the openRawResource(int) function, read that entire stream into a byte[], pass that byte[] into a String(byte[], String) constructor with the second argument being “UTF-8” and then, and only then, pass that string into the Simple XML read(Class, String) function to be read. Doing that will ensure that the bytes from your input stream will be read with the correct character encoding and that you will be able to parse the file correctly.

That is the only caveat that I came across in my use of Simple XML on Android and it has a big Sourceforge page that I created looking into the issue.

Conclusion

In summary, this is how you can use an easy annotation based XML serialization framework on Android (that gives JAXB like functionality). It is very flexible and easy to use, and will make your projects easier to write. I know that this was a bit of a long post so thankyou for sticking with me; I hope that you get some good use out of this and that it helps those Android developers out there.

Android

Setup Android Honeycomb Development on Ubuntu in Eclipse

Here are the steps that you will want to take to start Android Honeycomb development on Ubuntu (or even Windows for that matter). This guide assumes that you have an internet connection and Eclipse: Helios installed:

  1. Goto the Android Developer pages and Download the SDK.
  2. Install the SDK and place it in a location in your filesystem. (Remember this location because later, it is required to setup the Eclipse ADT plugin)
  3. Run the SDK manager and install all of the avaliable Android packages; this may take some time depending on your internet connection speed.
  4. Fire up Eclipse Helios and goto: Help -> Install New Software…
  5. In this section you will want to add two new repos to Eclipse and they can be found on this google code page and the ADT repo from the Android developer pages. Instructions are provided in the links.
  6. The second repo that you installed contains the ADT plugin; select that repo from the list and install the ADT plugin. Once you are done you will be prompted to restart eclipse which you should do.
  7. Once Eclipse has restarted you will want to let the ADT plugin know where you installed the SDK. To do this go: Windows -> Preferences and then Click on the ‘Android’ preference tab; a window should appear that asks you for the ‘SDK Location’. Put the filesystem location of the Android SDK in that box and hit apply. If many targets appear after a few seconds then you have done it correctly. Now press OK to exit the Preferences.
  8. Go back and run SDK manager again. In here create an Android virtual machine for the type of Android Project that you would like to develop. Remember that the more RAM that you give the VM the better but the emulator will probably still be slow; try and mirror a real device.
  9. In Eclipse, press Ctrl+N and create an Andriod project from the menu. First select the version of the SDK that you would like to use and then I recommended selecting one of the test projects that are avaliable for that SDK.
  10. Run the project from the eclipse run menu as an Android Project and watch it run in an emulator.

And that is all that there is to it. Perhaps a few more steps than you would expect but once you are done you will have a complete Android Honeycomb development environment. If you have any questions or want clarification then please ask it in the comments.