I’m slowly getting my various Android projects up to bitbucket, codeplex or another open/public DVCS and I’m slowly making sure that all of them can have auto-magic continuous integration. As my Windows Home Server is running TeamCity for MahTweets, its natural I want to keep it all contained in that.
Originally I was trying to use the Ipr build runner, as I’m currently using IntelliJ IDEA, which is picked up by TeamCity rather well except it only generates a bunch of .classes (so it is compiling) but none of the dex/APK’s required for Android.
The only solution I could find is to use Ant!
Generating the Build.Xml
When I created projects in NetBeans, Eclipse or IntelliJ, none of them created the Build.xml file for your project. Luckily the Android SDK does.
You’ll find "android" under the tools subfolder in the SDK. From a command line:
android create project –n <ProjectName> –t <Target> –p <PathOnDesk> –k <Package> –a <Activity>
All values are required. As I’d already created my project, I stuck in some dummy values and just grabbed the build.xml out of that folder, and placed it into my project folder. I used:
android create project –n OhHai –t 1 –p D:\OhHai\ –k MahApps.OhHai –a OhHaiActivity
Make sure you commit the build.xml to your VCS!
BuildAgents
Your BuildAgents are going to have to have a few extra requirements – primarily the Android SDK as well as the SDK for the particular version you are building against (run the SDKSetup inside the SDK download).
Once you’ve done that, you need to add a property to your BuildAgent to point to the location of the SDK you’ve just downloaded. Edit your BuildAgent configuration (by default on Windows, its C:\BuildAgent\conf\buildAgent.properties) by adding
android.platform.base=pathToSDK
To the end of the file. This will disconnect and then reconnect your BuildAgent from your BuildServer. For me, it was
android.platform.base=D\:\\SDKs\\android-sdk-windows
You’ll notice this isn’t the path to the individual SDKs, and that’s because the ant tools build.xml calls are under <SDKRoot>/tools/lib
New Configuration
Most of the values can be configured as normal, ie, give it a name, select your VCS, trigger, dependencies etc There are only a few extra values you’ll need to throw in
- General Settings
Artifact path: /bin/YourProjectName-debug.apk
- Runner
- Select Ant as the build runner
- put build.xml as the path to your build file (unless you’ve changed the name of it)
- put ‘debug’ as your targets (unless you want another build target)
- Add an Additional Ant command line parameters, put in -Dsdk.dir="%android.platform.base%"
Ant properties are passed in via the command line as –DparamName=ParamValue.
Personally, I’ve added an additional Configuration Parameter Requirement, of android.platform.base to make sure only the BuildAgents with it configured attempt to build it.
Voila, build the project (and providing it doesn’t have compile issues), your APK should be the only file in your artifacts!
While I’ve outlined some of the programmatic differences between WP7 and Android, there is often a lot more to it than that – how easy is it to get the environment up and running? How easy is it to learn?
Getting the SDK/Tools up and going
WP7′s SDK can be found through developer.windowsphone.com portal (download is on the standard Microsoft downloads, but developer portal is the easiest way to grab it), you grab the 69kb web bootstrapper, which then downloads up to 339.8MB, installs the various tools and you’re right to go – from Visual Studio or Blend, you can go File –> New Project –> Select Windows Phone.
Android’s SDK is found on the developer.android.com portal, grab the appropriate version for your operation system, make sure Java 5 or 6 is installed, then once you’ve unzipped the SDK, you’ll need to run SDK Setup, which lets you choose and download which version of the SDK you’d like. Android is relatively fragmented, so you need to download the SDK for the lowest version of the API you’d like to target – that is, if you want to run on Android 1.6 and above, download 1.6 (version 4 of the API) and then you can target that/make virtual machine with 1.6 on it.
By default, the SDK Setup tool will query https://dl-ssl.google.com/android/repository/repository.xml for the latest information, but that has never worked for me on a variety of machines. You’ll need to go into the Settings for SDK Setup and tick ‘force https://… sources to be fetched using http://…’
Once you’ve got the SDK up and running, you may as well create a Virtual Device, unless you plan to do all your debugging on a device.
Finally, you’ll need to setup your IDE of choice – Eclipse has a plugin from Google with its own set of hopes to jump through, IntelliJ IDEA Ultimate ships with Android support, and NetBeans has an unofficial/unsupported plugin. And finally, now you can start a new Android project.
Winner: WP7 – set and forget, done. Android you have to earn it.
Included SDK/Tools
I should stress this is about the free SDK/Tools included, not any third party purchased tools.
WP7 includes
- Visual Studio 2010 Express for Windows Phone
- Expression Blend 4 Express for Windows Phone
- XNA
- WP7 Emulator
You cannot, however, select what components you want although thankfully its smart enough to figure out that if you’ve got VS2010 Standard or above to not install another copy of VS.
Android includes
- SDK Tools
- Dalvik Debug Monitor
- Draw 9 Patch
- Android Emulator
- Android Emulator manager which lets you create different VM configurations (storage/screen res/etc)
- SDK version downloader/manager (download more versions
- Eclipse Plugin
While at first glance you would be forgiven for thinking WP7 is superior as it includes a full IDE and a UI designer, there are a few caveats. The Android Dalvik Debug monitor can attach to either a VM/Emulator or a real device – meaning you get full file access/exploration, full debugger output, device querying, radio querying, ability to take screenshots from the device and more. While these tools don’t trump Visual Studio in most, having no way to query a physical (or emulated) device for WP7 or to take a screenshot is going to be very frustrating.
Not this is based on Windows Mobile/CE experience rather than WP7 experience – why? I have a Windows Mobile device, but I do not/cannot get a WP7 device just yet, unless a Microsoftie wants to donate one of the 90,000 or so Microsoft are giving away to employees.
Winner: Not clear (leans towards WP7)
Emulator/Virtual Machine

Hands down, WP7 emulator is faster. I timed my first WP7 app from cold boot to being in my application…. 7.5 seconds. That’s insanely fast. It is, however, showing it’s beta-ness. I’ve managed to crash it – which just meant it closed, no restarting, it doesn’t respond to keyboard input – which means you have to use the onscreen keyboard using your mouse.
There doesn’t seem to be a way to start up the WP7 emulator without using Visual Studio or Blend, but I may just be missing something (why would you want to do this? Well, you might want to test the horrible browser on WP7 to make sure it works with your site). This is a downside but it is fairly easy to work around considering how fast VS2010 and the emulator boot.

The Android VM is sloooow. Even on my quad core system, it 32 seconds for the OS to boot, let alone deploy and start up my app. And it’s relatively buggy too – icon’s are supposed to scale with the resolution of the VM but more often than not on my WVGA VM it doesn’t scale leaving the UI stretched or overly spaced.
On the plus side, crashing the Android VM results in the virtual device rebooting itself inside the VM instead of just closing, it also responds to full (physical) keyboard input, and has a wider variety of installed apps to interact/test with.
Winner: Not clear (leans towards Android, seriously, lack of keyboard input on WP7 bites)
Documentation
"Back in the day" JavaDocs were all the rage, but that was a long time ago. Android’s documentation is barely more than JavaDocs for Java and Android API’s available. While there are some examples, they’re not entirely useful or beyond basic "Hello World" given the complexity that Android has.
Google has Android Docs?!?!?!?! I thought those were templates for future use
Ive been working with the SDK since it has been out and the one thing i have learned is reading those docs is about as useful as trying to light a fire with a squirt gun. Its easier to go onto the github and rip apart their source to see the truth
Those are two tweets in response to when I said the Android docs weren’t that good.
On the flip side, MSDN has come a long way in terms of visual and cross browser appeal in the last few years. In general, the MSDN docs are detailed enough and generally contain a sample in C#/VB/XAML.
Winner: WP7, and by a big margin. MSDN rocks my socks.
Winner?
Again, there are no winners here – both have their positive and negative elements. I’d compare debugging but that’s a little unfair until I’ve got a WP7 device to compare against.
WP7 is easiest to get going, and has better documents, but some of the tools are lacking and the VM is a little frustrating.
Android is daunting to get going and you’re better off reading other people’s code/Android’s source code than reading the Android docs
(I’m happy to have devices donated to compare…Microsoft, same goes for you HP/Palm on WebOS, or Apple if they want to send me a Mac Mini+iPhone)
I’m a PC and I’m a big fan of WPF, so it could be assumed that I like Silverlight and therefore WinMoPhone 7. Well, the truth is I love WPF but think that Silverlight is more like WPF vPainful, and I use Android which has some fantastic hardware and is available now unlike the mythical Windows Mobile 7.
It wasn’t until the recent spat of previews coming out from places like Engadget that I was even vaguely interested in WinMoPho – seeing the simplified design of Metro on AMOLED screens looks fantastic. Some would say it lacks depth and is a bland design. In many ways I agree but as Microsoft have rather strict requirements for WinMoPho devices including OLED as a minimum (no LCD!) I’m beginning to see the beauty in it when compared to the reasonably complex (visually) Android particularly when out in the sun.
From a dev point of view, there are strengths and shortcomings for both systems, and I’m not entirely sure who is the clear winner, if there can be one.
IDEs and tools
Dev tools
Okay, so an IDE is never required, but I like to be productive and don’t memorise every namespace. Android is Java based, so naturally the top choice for IDEs are all Java based as well – the three I’ve tried are Eclipse, Netbeans and IntelliJ. Personally I think IntelliJ is the best, although it’s not free if you want to do Android development. These run on *Nix, OSX or Windows, giving you greater flexibility in your development. Eclipse is as close to the ‘official’ IDE as it gets – Google provide the plugin for it – but there is no IDE directly from Google. This is good in that you can use whatever you are comfortable in, but bad because the general tooling is pretty below par.
WinMoPho has Visual Studio 2010 Express for Windows Phone. It’s a mouthful, but personally I think its justified as its just that much better than the offerings for Android. VS10 Express is free (or you can use the professional versions of Visual Studio), but only runs on Windows which may hinder some. While it is an incredibly complex piece of software, it is also incredibly powerful.
The debugging is just.. well.. better on VS. And IntelliSense works. Eclipse’s auto-complete names all the arguments arg0, arg1 .. argN, I could never get NetBean’s debugging to actually debug and IntelliJ is case sensitive – it won’t pickup Hello for helloWorld.
Design/UI tools
The WinMoPho Developer tools “ship” with an Express version of Expression Blend (Express Expression Blend… another nice name) which will only let you do WinMoPho development. This is free, and will remain free. Eventually it’ll install into regular (non-free) versions of Blend. Blend is, without a doubt, awesome. I won’t bore you with lots of details, but it is a designery app for designing your applications UI. How designery? Blend 4 can directly import Photoshop (PSD) or Illustrator (AI) files – AI goes straight to XAML/Vectors, and PSD will try to map text layers up to Textboxes, rectangles, etc – your layer structure keeps intact!

In contrast, Android has no UI editing program, but there is an editor for Eclipse. Sadly, the editor is absolute balls – you can’t drag controls around, you can’t resize, etc. The closest to something useful is the unofficial DroidDraw java applet. I think DroidDraw is mostly limited by the poor layout system that Android has.

Multitasking
Android has it, WinMoPho doesn’t. I think it is rather stupid of Microsoft given the current mobile climate, but whatever. Android apps have multitasking built into them, even the default Google applications use the same API’s – no hidden secrets or limitations that other OS’s have/have had. There are just a few caveats to be aware of
- your application could be terminated at any time if its not in the foreground, if the device start running low on memory
- every time the user switches back to your application (even after it is killed), the view is recreated as it was in the onCreate method of your Activity unless you override onResume as well.
- Your application should always go back to the previous Activity it was on when they left – Android handles this automatically.
- You can explicitly run in the background so that Android doesn’t kill off your application if you use Services or BroadcastRecievers – think music playing app, IM, etc.
Sharing, Intents and Navigation
One thing thing that WinMoPho completely lacks is one of the greatest strong points of Android – the ability to share data between applications, but without having to specifically target an application. For example, if you take a photo then press share, any application that has registered the correct intent for sharing will appear in a list – email, a variety of Twitter clients, Flickr, Facebook, whatever, so long as its registered, it can handle it.
In Android, you register an Intent with the OS to replace pretty much anything that matches that – such as the Homescreen. That’s right, things as basic/essential as the homescreen can be replaced – how awesome is that?
<activity android:name=".AlbumListActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:screenOrientation="portrait"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
In MahTunes I’ve registered the AlbumListActivity to hook up to the “Launcher” activity – this just means it’ll appear in the “app tray”, and that it should launch this activity first. Intents are registered via the AndroidManifest.xml that every Android app needs.
Navigation
Navigation in Android is through Intents whether it is between applications or inside a single application.
Intent playbackIntent = new Intent(getApplicationContext(), PlaybackActivity.class);
Track t = (Track)tadapter.getItem(arg2);
playbackIntent.putExtra("trackId", t.ID);
startActivityForResult(playbackIntent, 0);
This example is also from MahTunes, inside the track selection dialog, it creates a new Intent to target the PlaybackActivity class and loads it up with some primitive data – you can only pass along primitive types, no objects.
If you’re querying another application, the Intent constructor parameters would look like
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
At the other end, inside PlaybackActivity’s onCreate, it can query the intent “bundle”
long trackId = getIntent().getLongExtra("trackId", -1);
There is one downside – moving from screen to screen inside your own application in Android feels more like a collection of “activities” rather than a proper application, as you pass data around from one to another. There is the (optional) Application class to extend which acts as a global wrapper around them.
WinMoPho navigation around an application isn’t much different. It treats everything as a “page”, so you use Uris to navigate around. This has the same problem of not being able to send complex datatypes to the new page all that easily. That being said, the “application” class isn’t optional, so you’ll always have that container.
NavigationService.Navigate(new Uri("Details.xaml", UriKind.Relative));
Data binding
Android doesn’t have data binding, it’s as simple as that. You can set X to Y, but you’re essentially just setting X to be an instance of Y – when Y updates, X doesn’t. Yes this is framework magic. Data binding and data templating are the two greatest things about WPF and Silverlight.
And this leads into the next point, Lists. Lists are hard, okay? Well, okay, I’m lying, lists aren’t hard at all on most UI frameworks but this is one of the greatest downfalls of Android programming. Unless you want a very basic list of just a string-per-line, Android requires you to create a custom ListAdapter which I’ve written about before. There are a whole stack of performance issues and enhancements you need to do to each and every one of your adapters – it’s just a messy and repetitive process.
Silverlight? myListBox.ItemSource = MyList; Done. That won’t automagically setup your UI to be bound the way you want it (in fact it’ll just give you a .ToString() of each object per line), but you don’t have to write any custom code to adapt a list to your ListBox.
List example

This is a screenshot taken from the Android Dalvik Debug Monitor (part of the Android SDK) of MahTunes running on my Milestone. You’ll notice there are issues with text-wrapping and originally there were issues with some items stretching further than others. Ignoring the rounded corners on both the background item and on the album art and ignoring the custom font, how do you do this in Android and in WinMoPho?
Android
AlbumListActivity.java (snippet from where the Activity sets the current view)
AlbumAdapter albumadapter = new AlbumAdapter(this, Albums);
ListView lvMyListView = (ListView)findViewById(R.id.ListViewAlbums);
lvMyListView.setAdapter(albumadapter );
AlbumAdapter.java
package mahapps.MahTunes;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import java.util.*;
public class AlbumAdapter extends BaseAdapter
{
private List<Album> elements;
private Context c;
public AlbumAdapter(Context c, List<Album> Albums) {
this.elements = Albums;
this.c = c;
}
public int getCount() {
return elements.size();
}
public Object getItem(int position) {
return elements.get(position);
}
public long getItemId(int id) {
return id;
}
public void Remove(int id)
{
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent)
{
LinearLayout rowLayout;
Album t = elements.get(position);
if (convertView == null)
{
rowLayout = (LinearLayout)LayoutInflater.from(c).inflate(R.layout.albumitemview, parent, false);
TextView tv = (TextView)rowLayout.findViewById(R.id.txtName);
tv.setText(t.getName());
tv = (TextView)rowLayout.findViewById(R.id.txtArtist);
tv.setText(t.getArtist());
ImageView iv = (ImageView)rowLayout.findViewById(R.id.imgAlbumArt);
iv.setImageBitmap(t.getAlbumArt());
} else {
rowLayout = (LinearLayout)convertView;
TextView tv = (TextView)rowLayout.findViewById(R.id.txtName);
tv.setText(t.getName());
tv = (TextView)rowLayout.findViewById(R.id.txtArtist);
tv.setText(t.getArtist());
ImageView iv = (ImageView)rowLayout.findViewById(R.id.imgAlbumArt);
iv.setImageBitmap(t.getAlbumArt());
}
return rowLayout;
}
}
AlbumListView.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView android:id="@+id/ListViewAlbums" android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>
AlbumItemView.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="fill_horizontal">
<ImageView android:id="@+id/imgAlbumArt" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/txtName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="false" />
<TextView
android:id="@+id/txtArtist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="false" />
</LinearLayout>
</LinearLayout>
WinMoPho
C#/Codebehind (snippet where the list is bound to the list of Albums)
lstMyList.ItemsSource = myListOfAlbums;
XAML/UI
<ListBox x:Name="lstMyList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image/>
<StackPanel>
<TextBlock TextWrapping="Wrap" Text="TextBlock"/>
<TextBlock TextWrapping="Wrap" Text="TextBlock"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
There are better ways to write the XAML than this, but this is the easiest way to demonstrate it.
Android has a tonne more code, a tonne more markup (and trust me, its needed), and it still doesn’t function 100% of the way it should and you’d have to rewrite a lot of that code if you wanted to do another list of tracks instead of albums. On Android if you add to the list, you have to make sure you notify the adapter so it can update whereas its automatic on WinMoPho.
Images
If you’re getting images on Android from anywhere but local storage, you’re going to have some fun times there – by that I mean images from the internet.
Android
Part of the issue is when do you download the image? In this example I was setting it in the custom ListAdapter, but this of course creates a very slow loading of the list – you need to spin this off to a different thread.
ImageView imgAvatar = (ImageView) rowLayout.findViewById(R.id.imgAvatar);
URL aURL = null;
URLConnection con = null;
try {
aURL = new URL(t.Avatar);
con = aURL.openConnection();
con.connect();
InputStream is = null;
is = con.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
Bitmap bm = BitmapFactory.decodeStream(bis);
imgAvatar.setImageBitmap(bm);
is.close();
bis.close();
} catch (MalformedURLException e) { }
catch (IOException e) { }
catch (IOException e) { }
Silverlight
There are several ways to set images – you can set the Source on an Image in XAML to the Uri, you can databind the Image’s Source in XAML to a property on the object you’re binding (can be a BitmapSource, String or Uri) or you can set it in code like Android. However, most of the time the first two options are what you’ll do, and the framework automatically takes care of loading it asynchronously. It really is that simple – its hard to stress how easy it is compared to Android.
One clever thing Android does do around images, however, is the Nine-Patch image. A NinePatch is like the name suggests, an image that can be divided into 9 sections, where the “inner” (5 if you were looking at it from a numberpad) section can be stretched for content. The editor for this is included in the Android SDK, although isn’t very friendly to use.

Persistence and Storage
WinMoPho will not give you direct access to the file system nor will it ship with (apparently its there, just not accessible) SQL CE. The only way you can store on the device is using IsolatedStorage, a concept brought over from the “desktop” version of Silverlight. That being said, Alex Yakhnin has created a LINQ Data Provider for Isolated Storage which works wonderfully by serialising objects to JSON, then storing in IsolatedStorage, which is incredibly easy to consume.
public static class Storage
{
private static ObjectStore datastore = new ObjectStore("MahBlogMobile");
public static ObjectContext Context = new ObjectContext("MahBlogMobile");
public static void StoreAccounts(IEnumerable<Account> account)
{
datastore.Persist<Account>(account);
}
}
Android by contrasts lets you write to the file system and comes bundled with SQLite. While it (seems?) to lack ORM’s like LINQ, it’s flexible enough to let you decide how you want to do it.
public int InsertProduct(Product P)
{
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
db.execSQL("INSERT INTO Products ('Barcode', 'Name') VALUES ('"+P.barcode+"','"+P.name+"');");
int id = 0;
Cursor c = db.rawQuery("SELECT ID FROM Products WHERE Barcode='"+P.barcode+"' AND Name='"+P.name+"'", null);
if (c.moveToFirst())
{
id = c.getInt(c.getColumnIndex("ID"));
}
db.close();
return id;
}
Device Resolution/Size Handling
WinMoPho will launch with WVGA (800×480) support only with HVGA (480×320) coming later on the track and only on phones (so no 10″ tablets), while Android supports FWVGA, WVGA, HVGA, FWVGA, QVGA, FWQVGA, WQVGA and various phone screen sizes and formats as well as tablets and portable media players. As such, Android has a harder time supporting all those devices, but has some clever ways to support these.
When you create a new project in any of the Android-compatible IDE’s, you’ll have a /res folder with /drawable, /drawable-hdpi, /drawable-ldpi and /drawable-mdpi inside of it. The idea is that you put your special version of your images into each folder and Android will be smart enough to know when to use each resource – ie, for your icon.png, you make it 72×72 for hdpi but mdpi is 48×48. You must declare in the manifest what screens you support, otherwise there is a good chance it’ll default to the wrong one.
While it’s great there is that level of support, the biggest issue is that the magic is based on density. According to Google, medium density is 320×480 on 3″ to 3.5″ screen OR 480×800/480×854 on 4.8″ to 5.8″ screens. Does this mean that a 5″ tablet is going to use a 48x48px icon instead of a 72x72px icon?
From a code point of view, getting the correct resource in said folders is performed in a similar magical way – R.drawable.icon refers to the correct density without having to figure that out yourself. That being said, you can do that
float scale = this.getResources().getDisplayMetrics().density;
Bitmap bdRounded = BitmapHelpers.getRoundedCornerBitmap(artwork, (int)(15 *scale), (int)(320 *scale), (int)(320 *scale));
In this instance, scale would return 1.0 on a low density screen and 1.5 on a high density screen.
What will WinMoPho require? At this stage it’s unclear what Microsoft are planning, but because Silverlight is a vector based layout system, many applications may not require changes as vectors scale rather nicely.
Winner?
I don’t think there is a clear winner – for some people Java is going to be more natural but for others its going to grate against everything they know. I think I personally need to more Android dev before I chalk it up to ‘not for me’.
WP7 clearly has some great things going for it – the .NET stack goes from web, desktop, phone, Xbox360, and various mono implementations. Android on the other hand has the flexibility that no other mobile OS offers and a very passionate developer base, with a user base starting to challenge the almighty iPhone juggernaut.
To be perfectly honest, I’ve not been overly happy with Eclipse. Yes, its free, yes its the recommended IDE for Android dev from Google, but it’s not the easiest IDE to adapt to. I’m sure its super powerful and whatnot, but there are several things that really irk me. My major complaints are:
- The concept of workspaces are stupid. Having to restart the IDE to change project? uuugh!
- When using the IDE to create methods (such as overriding), it tends to name all the arguments as argN, ie arg0, arg1, arg2
- Constant switching modes for debug/edit mode seemed crazy
I thought I’d give NetBeans (6.9Beta) a shot, having used so few Java IDE’s before. Like Eclipse, NetBeans is free, and has an Android plugin.
NetBeans has the ability to import Eclipse workspaces, but unfortunately will convert it to a standard Java project rather than an Android project. Never fear, Paul is to the rescue.
Converting Eclipse/Android Workspace to NetBeans/Android Workspace
- Install Netbeans Android plugin following the instructions from the NetBeans Wiki
- Fire up Netbeans, File –> Import –> Eclipse Workspace, and import as normal.
- Close Netbeans and locate the ‘nbproject’ folder for your new project – it should be <location of your project>\nbproject.
- First up, its worth replacing the build-impl.xml for an Android specific one. From what I gather, this file defines all the rules for compiling. Here’s the build-impl.xml that NetBeans 6.9 (beta) generated for me.
- Open up project.xml in your favourite text editor. You’ll need to change a few lines here.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="3"http://www.netbeans.org/ns/j2se-project/3">
<name>MahTweetsMobile</name>
<source-roots>
<root id="src.dir" name="src"/>
<root id="gen.dir"/>
</source-roots>
<test-roots/>
</data>
</configuration>
</project>
Change the first red line to: org.netbeans.modules.android.project
and the second line to http://www.netbeans.org/ns/android-project/1
-
Open up project.properties in a text editor, find the line starting with dist.jar – Android doesn’t use jar, but apk, so change dist.jar to dist.apk and the extension to .apk as well.
ie Change dist.jar=${dist.dir}/MahTweetsMobile.jar to dist.apk=${dist.dir}/MahTweetsMobile.apk
-
Next up, still inside project.properties, you have to add a few properties that don’t exist.
Add the following lines to the end of the file:
resource.dir=res
test.src.dir=test
intermediate.dex=${build.dir}/classes.dex
-
Save those files, fire up NetBeans and you should be good to go! If you get a build path error when opening the project, right click on the project (in NetBeans) –> Properties –> Libraries –> make sure the correct Android is selected from the drop down.
While delving further into Android, I’ve been creating a “hello world” type of app – its not as complex as what MahTweetsMobile will be, but it is encompassing a lot of different elements (custom ListAdapter, SQLite for persistent storage, different types of menus, loading external intents, etc).
One “difficult” element has been events. I say “difficult” because by design, its freaking nuts.
Scenario
I’ve got a custom ListViewAdapter, for my custom list elements, where the ListView items include a checkbox. This checkbox is to indicate the status of the items (for reference, its a shopping list app, you tick the checkboxes to show which items you’ve bought while shopping, the items then go grey in colour).

I wanted to add a “long press” context menu so that you could easily bring up a menu (with options such as Edit Item or Delete Item)
The Problem
Normally when “attaching” event listeners with ListViews, you use setOnCreateContextMenuListener on the ListView itself. You then override your Activity’s onContextItemSelected, figure out what menu button was pressed as well as what item it was pressed on.
ListView x = (ListView)findViewById(R.id.ListView01);
x.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
{
public void onCreateContextMenu(ContextMenu contextMenu, View view,
ContextMenuInfo arg2)
{
contextMenu.add(0,CMENU_DELETE, 0, "Delete Item");
}
});
public boolean onContextItemSelected(MenuItem item)
{
AdapterContextMenuInfo menuInfo =
(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
switch (item.getItemId())
{
case CMENU_DELETE:
//Use menuInfo.position along with the adapter.getItem
//ie Product p = (Product)adapter.getItem(menuInfo.position);
return true;
}
return true;
}
As you can see, its ugly code, but it works. Sort of. The problem was the checkboxes.
As soon as you add checkboxes to the individual items view, any listener created on the ListView never fires – the CheckBox swallows the event!
The Apparent Solution
Apparently this is a known bug (or more accurately, this is by design!). The solution is to set the event handlers on the rows themselves; inside the custom ListAdapter, when you’re inflating the various UI elements – look at my previous post on Custom ListAdapter, it’s under the getView method – on that “rowLayout” use the same setOnCreateContextMenuListener as the code used on ListView above, except only apply it to the individual row’s.
That would be fine if you didn’t care which item was pressed. That’s right, the cast to AdapterContextMenuInfo of item.getMenuInfo() in your Activity’s (yes, your activity has to override this, nowhere else works. argh!) onContextItemSelected always returns null because item.getMenuInfo() is always null.
The Actual Solution
I have no idea how I stumbled across this solution – I think I was in the process of undo-ing lines of code to try and figure out “where I’d gone wrong”.
Fact: To get the event to fire with checkboxes you need it to be set on the rowLayout.
Fact: To get menuInfo to be anything other than null (ie, tell you where it came from), you need it set on the ListView
Solution? Combine them. Wait, what? Two event listeners to get them to work? Yup.
On the rowLayout, set the listener:
rowLayout.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
{
public void onCreateContextMenu(ContextMenu contextMenu, View view,
ContextMenuInfo arg2)
{
}
});
Notice the lack of code inside the onCreateContextMenu? Well, any ContextMenu items added inside this method won’t have AdapterContextMenuInfo – so don’t set anything, no menus will appear.
Now also set the adapter on the ListView using the code above.
Now it all works. WTF doesn’t begin to describe this.
Disclaimer: This post presumes you’ve setup the Android SDK and Eclipse. If not, check out the Android Developer Guide
Some of the Android developer documents seem great, but in general there seems to be a lacking of documentation/examples – while the Java language is giving me no problems, how to do things with the Android API can be a bit of a nightmare to figure out.
It is possibly because Android is relatively new or because I’m used to MSDN which is a fantastic resource. Regardless, I started to want to develop MahTweetsMobile for Android and was having difficulty in ‘binding’ a ‘view’ to a list of elements, ala WPF/XAML’s DataTemplates.
It turns out its not as magical as what WPF is and requires manual binding, but its not impossible.
The View
To get a list to display anything other than just a string, you need to define your own view in either XML or code-behind. I find XML to be a little nicer, and its easier to update.
In Eclipse (I’m sure it’ll work in other IDE’s too, but this is what I’m using), you can create a new view by navigating to res –> layout, right clicking on the folder and selecting New –> Other, then from the popup select Android –> Android XML File
Make sure in the next dialog you select the Layout resource type, and give the file a name like "tweetview.xml" (all in lower case, as java/ADK will complain otherwise).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/widget32"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TableLayout
android:id="@+id/widget33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TableRow
android:id="@+id/widget35"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageButton
android:id="@+id/imgbtnAvatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</ImageButton>
<LinearLayout
android:id="@+id/widget39"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
>
</TextView>
<TextView
android:id="@+id/txtTweet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
>
</TextView>
</LinearLayout>
</TableRow>
</TableLayout>
</LinearLayout>
The Model
Just a simple class to hold our data,
package mahapps.MahTweets;
import java.util.Date;
public class Tweet {
public int ID;
public String Name;
public String Text;
public Date Timestamp;
public int getID()
{
return this.ID;
}
public String getName()
{
return this.Name;
}
public String getText()
{
return this.Text;
}
public Tweet()
{
}
}
The Custom ListAdapter
This is the "heavy lifting" code – this is what "binds" a Tweet object to the TweetView.
package mahapps.MahTweets;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import java.util.*;
public class TweetAdapter extends BaseAdapter
{
private List<Tweet> elements;
private Context c;
public TweetAdapter(Context c, List<Tweet> Tweets)
{
this.elements = Tweets;
this.c = c;
}
public int getCount() {
return elements.size();
}
public Object getItem(int position) {
return elements.get(position);
}
public long getItemId(int id) {
return id;
}
public void Remove(int id)
{
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent)
{
LinearLayout rowLayout;
Tweet t = elements.get(position);
if (convertView == null)
{
rowLayout = (LinearLayout)LayoutInflater.from(c).inflate
(R.layout.TweetListView, parent, false);
TextView tv = (TextView)rowLayout.findViewById(R.id.txtName);
tv.setText(t.getText());
//...
//and so on for all the properties/UI elements
//...
} else {
rowLayout = (RelativeLayout)convertView;
}
return rowLayout;
}
}
You can then use this in your main Activity:
ListView x = (ListView)findViewById(R.id.ListView01);
x.setAdapter(new TweetAdapter(this, MyListOfTweets));
If you’re using a ListActivity, you’d just set that Activity’s adapter.
Your ListView items should then appear in more detail!

Disclaimer: I’m new to Android, I could be doing this all wrong. If I am, please comment and correct me.
Programming for Android is an interesting experience, coming from a .NET/C# background. I’ve done plenty of Java before in Uni and disliked it, but that was before I started playing with WPF.
Like WPF, Android’s UI is created using XML based documents, but unlike WPF, there aren’t any nice WYSIWYG builders. And most of the time it seems you need a combination of code behind and XML to get what you want for the UI, which can get a bit frustrating.
The divider between the items in this particular app is more annoying than it is useful, so I wanted to get rid of it. I was initially looking for separator or border, but the name is divider, and it has two properties.To set the divider between the ListItems to "nothing", you have two options. The first is in Java,
ListView x = (ListView)findViewById(R.id.ListView01);
x.setDivider(null);
x.setDividerHeight(0);
The alternative is to set it in XML, but in this case its more of a hack than the above of turning it ‘off’.
<ListView
android:id="@+id/ListView01"
android:background="#ffffff"
android:dividerHeight="0px"
android:divider="#ffffff" />
Even though the dividerHeight is set to 0 (0px, 0dp, whatever, the results were the same), a black line was still visible. The best solution is to set the colour (the divider value) to the same as your background. Using a gradient or image as the background? Set it in the code behind.

Google products and services range from ‘awesome’ down to ‘wtf’ (*cough*Orkut*cough*), and their single signon/identification system ("Google Account") sits somewhere between the two.
On Android, just about everything is tied to a Google account. No big deal, I use Google Apps 4 Domains (GAFD) and I’ve used an email address associated with that to create a GoogleID which I use for Google Reader and other products.
To be honest, I was a little confused initially when the newly created GAFD account didn’t also create a GoogleID, but no big deal, I created my own. As far as I know, everything has worked – I even have a Google Checkout account. Even on the Android everything was working great, syncing contacts/email/calendar/etc, all was swell – until it got to the Market.
Using a GAFD based GoogleID doesn’t let you purchase apps. You can see the ‘buy’ button, but when you go to buy, it’ll go through an infinite loop of asking for a Google Account.
Midway through 2009, a Google employee responded to a help thread
At the moment, Google Apps accounts may not be used for Google Checkout transactions, so Android Market requires the additional login to a Gmail account that is used for payments. However, this doesn’t mean that users will need to wipe their phones. The rest of the phone itself is still tied to the primary account that was signed in at start-up; in your case, the Google Apps account.
They acknowledge the problem, and surely would have fixed it by now in 2010, right? Wrong. The user in that particular thread bought a Nexus One through his GAFD based account with Google Checkout, so it’s good enough to buy a phone, but not a $0.99 app? Great.
Sorry to hear you’re having trouble purchasing apps. It sounds as if you’re logged in with a Google Apps account. When prompted to enter the Checkout account, please be sure to enter a non-Google Apps account to ensure that the purchases can go through. Let us know if you’re had success purchasing since your post.
Hopefully this will help somebody else, but the only solution is to also add a @Gmail account. And even then, you better hope your carrier doesn’t block App purchases (like say.. Optus do)
Again, thanks to Will I’m now on my second Android phone, this time the flagship Android phone from Motorola – the Milestone (the GSM version of the Droid).
The quality of the photos of the device are a little so so – I’m fighting off sinusitis and bronchitis at the moment, so I just don’t care.
The Good
I think the design is one of those "love or hate" designs – it has rather striking straight lights and "sharp" corners, unlike most phones these days. It’s weightier than it probably needs to be, but that gives it an incredibly solid feel to it.
There is a lot to like about this phone, however there are two stand out features (for me)
- I feel the need, the need for..
Speed. This thing is fast. The difference between the speed of this phone and all others I’ve had/used before is impressive. While ~50mhz slower than the iPhone, or ~450mhz slower than the Nexus One’s 1ghz Snapdragon processor, the Milestone has a dedicated GPU. It gets shit done.
- The Screen
The screen specs are 3.7", 854 x 480px, TFT LCD, 16M colours.
Yes, it drains the battery, but damn it looks good. I was a little concerned thinking that all the text would be tiny compared to the Dream (480 x 320 – same as the iPhone), but for the most part it just makes text so much clearer and easier to read.
Apparently the Nexus One screen (which has the slightly lower resolution of 800 x 480) is even better than the Milestone, which is scary awesome.
The Bad
Not everything is perfect on the Milestone, however. These complaints however, are (mostly) me nitpicking as much as possible.
- The Keyboard
See below in the comparison against the Dream for details, but the keyboard sucks. Still better than onscreen however.
- MicroSD Slot
The MicroSD slot is unfortunately impossible to get to without removing the battery. This is annoying because it somewhat defeats the obvious argument against internal-only storage of "you can have multiple SD cards and change whenever you like"
- The Camera
Don’t get me wrong, a 5mpx + Dual LED flash is neat. It takes good enough photos and video. For the sensor the size it is, 5mpx is overkill and creates some extra ISO noise but again, the photo quality is good enough.
The problem I have with the (still) camera is the desire to use the flash in every situation – that is, every time I’ve tried to take a photo, it’ll use the flash if ‘auto-flash’ is enabled.
Below, on the left is flash disabled, and on the right with auto-flash enabled. The irony is is, apart from the shot without the flash having better/more accurate colours, the flash actually make the image blur!

Against the HTC Dream
The obvious comparison for me is between the Dream and Milestone, but mostly it should be considered an unfair comparison. For starters, the Dream was released in October 2008 whereas the Droid/Milestone in November 2009, and while the G1 wasn’t considered the lowest end in its day, it was never a real "premium" phone, which the Milestone clearly is.
Specification wise, nearly everything is better – faster CPU, higher res screen, more onboard flash, better camera, better Bluetooth support, the list goes on. However it is interesting to note that the Milestone doesn’t win in all categories.
Keyboard
Like the Dream, the Milestone is a slider with a qwerty keyboard. However unlike the Dream, the Milestones keys don’t have a gap between each key, are far flatter, and have less "travel".
The key advantage physical keyboards have over onscreen keyboards is the tactile response, whether it is being able to tell where one key ends/starts because of the key separation or by having to push the key down (rather than float over it).

Apart from the less than ideal keys, the keyboard layout itself is a little funny. Instead of a five row key layout, they’ve gone for four which results in requiring alt to be pressed to enter a number. Although not as big a problem as the keys themselves, it is still a little frustrating.
Without a doubt, the Dream’s keyboard is just simply better.
It is interesting that the lower end Motorola Devour coming out seems to have a far better keyboard (Motorola promoting the raised keys)
Hardware Buttons
While the Milestone is not devoid of hardware buttons, Motorola’s choice of input is a little… lacking? Two (fairly standard) buttons are missing ("accept call" and "end call"), and unlike the Dream (and many Blackberrys) the scroller is gone in favour of a D-Pad which is hidden unless you slide out the keyboard.
Build Quality
There is no comparison here, and this is part of what I meant by the Dream not being a premium phone – the Milestone is just so solidly built with far better finish. The best example I can think of is the sliding mechanism – on the Dream it’ll rattle if the phone vibrates (call/notification/etc), whereas the Milestone is just solid.
Android 2.x
Apart from neat hardware, the other thing that the Milestone is rocking is Android 2.0.1, and what a difference it makes. Apart from everything seeming so much smoother and faster, Exchange support is built in! There are lots of improvements, but to be honest, I’ve barely scratched the surface of Android 1.6 let alone 2.0!
Google have a fairly detailed list of highlights for Android 2.0
I think the Contacts API is interesting, it allows multiple data stores for a single contact, so you could sync Facebook contacts to Gmail contacts. The Facebook app doesn’t work 100% for the Milestone (does for Droid/Nexus One) just yet, but it looks interesting. As does the possibility of extending this with Twitter/MahTweets Mobile.
Thanks to Will, I’ve now got an Android phone. The HTC Dream/Android Developer Phone 1 to be exact.

I’ve had my HTC p3600i for almost two years now; I wrote that review not long after I bought the device, and it wasn’t long after it that the flaws started to show. As I did mention, browsing was useless with PocketIE, but over time the device just became less and less stable. In the last two or three months, the phone has insisted that its roaming unless I reboot it – then it’ll work for about 15-20minutes.
The developer experience for Windows Mobile 6.0 (and presumably 6.1 & 6.5) was also a nightmare. I once started looking at creating a Twitter client for it, and I discovered that to get TextWrapping on a TextBox (under .NET CF), you had to override the Draw method of the Textbox. Already I’ve created more for Android than I did for Windows Mobile, and it’s still at the proof of concept stage! (More on that in a later post)
I’m really enjoying the relative responsiveness of the Dream/Android, as well as much nicer UI. Having a physical keyboard again is awesome, I don’t think I could go back to an all touchscreen phone. A usable browser is also a nice change – I can finally do net banking on my phone, should I need to.
That’s not to say Android or the Dream are flawless.
- Battery life sucks,
- I’ve had more than a fair share of various parts of Android (such as the Home screen) lock up,
- Android 1.6 has no Exchange support (although this is in 2/2.1, it’ll be awhile – if ever – before the Dream gets the upgrade because of
the relatively small partition for the OS not enough RAM – thanks for the clarification Bck),
- Many applications (including the “Google Experience” apps) default to notifications/always running/syncing requiring disabling the settings.Gmail, despite turned off under Settings –> Data Synchronisation –> Auto-sync (and Auto-sync turned off completely) always seems to sync as soon as Background Data is enabled, so I have to leave that off, which then disables the Market!Disabling Background Data warns/informs that disabling it will save power and data, but some applications require it and still use the connection!
- While the UI is pretty good, a lot of it is incredibly unintuitive. Some of the submenus in Settings have additional menu (activated by pressing the Menu button), but there is no visual indicator nor do all of the submenus respond to it.