Skip to main content

Android Development with Maven - a primer

Posted by johnsmart on November 1, 2010 at 1:48 PM PDT

If you are a Java developer, and you want to write software for mobile devices, Android is without a doubt the most accessible mobile development platform out there. The reason for this is simple: you write your applications in Java, using tools that you are already familiar with (notably Eclipse). Because of this, the the learning curve is a lot gentler than learning to develop on IOS for the iPhone or iPad, which involves also learning a whole new language. And, as we will see, you can also benefit from all the great tools and techniques (unit testing, automated builds, Continuous Integration and so forth) that you are used to in a Java development environment.

This article is not about writing Android applications, though that is a fun topic too! This article is about integrating an Android process into the broader automated build infrastructure. It is the first of two-part series - this article will look at how to automate your Android build process with Maven. The second part will look at automated testing and Continuous Integration on the Android platform.

Eclipse is typically the development environment of choice for an Android developer. Android provides an excellent Eclipse plugin, which makes a lot of tasks related to Android development a lot easier. This includes both real-time Android-specific error checking, as well as building your Android application and deploying it to an emulator for testing.

However, a nice Eclipse plugin does not an automated build process make, and there are still a lot of Maven features that I miss, such as Declarative Dependency Management and a clean release process. Fortunately, there's a Maven plugin for that! Unfortunately, it's a little bit tricky to get the two tools to play nicely together. In this article, I will take you through the basics of using Maven with Android, pointing out a few tips and gotcha along the way.

Getting started

I will assume you have installed the Android SDK on your machine, as well as the Eclipse plugin - if not, download the SDK from the Android web site and install it as per the instructions on the site (see the Android SDK site), and then install the Eclipse plugin. You will also need to install the platform versions you need (see here for more details). So far, all this is standard practice with classic Android development using Eclipse.

Once you have Eclipse configured correctly, you can create a brand new Android project to play with (File->New->Android Project). Again, there are plenty of examples and good books on how to do this, so I won't dwell on the details here.

Android and Maven

Eclipse is fine, but a serious Java development project needs an automated build script; we'll be using Maven. To get Android to work with Maven, you need to do a couple of extra steps. First of all, set the ANDROID_HOME environment variable to point to your Android SDK installation, e.g.

export ANDROID_HOME=/opt/android-sdk-linux

The Maven Android Plugin needs this environment variable, both on the command line and from in Eclipse, to work properly.

You should also add the Android plugin group to your settings.xml file, so that you can invoke the Android plugin more easily from the command line:

<pluginGroups>
  <pluginGroup>com.jayway.maven.plugins.android.generation2</pluginGroup>
</pluginGroups>

Make sure you create an emulator in the Android AVD Manager if you haven't already done so. The name you use here is the name that you specify in the android plugin configuration, in the avd section.

Next, you need to set up a Maven pom.xml file for your project. The simplest approach at the moment is to just create a pom.xml file manually in the project directory. An example of such a pom.xml file is shown here:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.wakaleo.training.android.qotd</groupId>
  <artifactId>QuoteOfTheDay</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>apk</packaging>
  <name>QuoteOfTheDay</name>
  <dependencies>
    <dependency>
      <groupId>com.google.android</groupId>
      <artifactId>android</artifactId>
      <version>2.2.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.google.android</groupId>
      <artifactId>android-test</artifactId>
      <version>2.2.1</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-all</artifactId>
      <version>1.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.8.5</version>
      <scope>test</scope>
    </dependency>

  </dependencies>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <testSourceDirectory>test</testSourceDirectory>
    <plugins>
      <plugin>
        <groupId>com.jayway.maven.plugins.android.generation2</groupId>
        <artifactId>maven-android-plugin</artifactId>
        <version>2.6.0</version>
        <configuration>
          <sdk>
            <platform>8</platform>
          </sdk>
          <emulator>
            <avd>em22</avd>
          </emulator>
          <deleteConflictingFiles>true</deleteConflictingFiles>
          <undeployBeforeDeploy>true</undeployBeforeDeploy>
        </configuration>
        <extensions>true</extensions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
      </plugin>
    </plugins>
  </build>
</project>

There are a couple of interesting things in this pom.xml file. First, the packaging type is apk, indicating that this is an Android application. In the dependencies, the android and android-test libraries are listed as provided, as they will be available on the device. And we overrode the default source directory and test directory to play nicely with the Android Eclipse project setup.

This pom will now let you do a range of common Android tasks from the command line via Maven. For example, building your application is simple: just run mvn clean install, as you would do with any other project. To deploy your app to the emulator, you will need to start the emulator, either from the Android AVD Manager, or from the command line. To start the emulator from the command line, you can run mvn android:emulator-start. The emulator might take a minute or two to start up properly, so be patient:

$ mvn android:emulator-start
[INFO] Scanning for projects...
[INFO]                                                                        
[INFO] ------------------------------------------------------------------------
[INFO] Building QuoteOfTheDay 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-android-plugin:2.6.0:emulator-start (default-cli) @ qotd ---
[INFO] Android emulator command: /opt/android/android-sdk-mac_x86/tools/emulator -avd em22
unknown
[INFO] Starting android emulator with script: /var/folders/y+/y+a+wZ-jG6WKHEm9KwnSvE+++TI/-
Tmp-//maven-android-plugin-emulator-start.sh
[INFO] Waiting for emulator start:5000
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.836s
[INFO] Finished at: Thu Oct 28 14:34:40 NZDT 2010
[INFO] Final Memory: 8M/81M
[INFO] ------------------------------------------------------------------------

And to deploy your application to the emulator, just run mvn android:deploy:

$ mvn android:deploy
[INFO] Scanning for projects...
[INFO]                                                                        
[INFO] ------------------------------------------------------------------------
[INFO] Building QuoteOfTheDay 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-android-plugin:2.6.0:deploy (default-cli) @ qotd ---
[INFO] /opt/android/android-sdk-mac_x86/tools/adb [install, -r, /Users/johnsmart/Projects
/Training/android/android-quote-of-the-day/quoteoftheday/target/qotd-0.0.1-SNAPSHOT.apk]
[INFO] 1068 KB/s (13169 bytes in 0.012s)
        pkg: /data/local/tmp/qotd-0.0.1-SNAPSHOT.apk
Success
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.537s
[INFO] Finished at: Thu Oct 28 14:35:25 NZDT 2010
[INFO] Final Memory: 8M/81M
[INFO] ------------------------------------------------------------------------

Back to Eclipse

Now that you can build and deploy your Android apps with Maven, you need to get Eclipse to come to the party. Now the normal way to activate Maven features on a project is via the 'Maven -> Enable Dependency Management' menu. Unfortunately, this won't work immediately. To make it work, you need to install the m2eclipse Android Integration plugin, which basically helps m2eclipse and the Android Eclipse plugin talk to each other. So install this plugin, and then enable Maven Dependency Management on your project.

You should now be able to run your Maven-enabled Android project as if it was an ordinary Eclipse Android project, using "Run As->Android Application". This will start the emulator and deploy your application, or just deploy it to a running emulator if one is available:

You can now build, deploy and run your Android application both from Eclipse and via Maven. This opens the door to an automated build job that you can set up on your local CI server.

In the next part of this series on Android development, we will look at automating unit and integration tests in Android, and how to set up Continuous Integration for your Android project using Hudson. Stay tuned!

Related Topics >>