a little madness

A man needs a little madness, or else he never dares cut the rope and be free. -Nikos Kazantzakis

Zutubi

Android Ant Builds: Targeting a Specific Device

While developing for Android, I often have more than one device available. For example, I might have an actual G1 hooked up via USB, and an emulator instance running. In this case, when installing and running development versions of my Android applications, I need to specify which device to target. If I’m working directly with adb, there are flags for just this purpose:

jsankey@caligula:~$ adb -?
Android Debug Bridge version 1.0.26

 -d                            - directs command to the only connected USB device
                                 returns an error if more than one USB device is present.
 -e                            - directs command to the only running emulator.
                                 returns an error if more than one emulator is running.
 -s <serial number>            - directs command to the USB device or emulator with
                                 the given serial number. Overrides ANDROID_SERIAL
                                 environment variable.
...

I prefer to use the general -s flag, as this works no matter how many devices I have connected. This does require a serial number, but they are easily listed:

jsankey@caligula:~$ adb devices
List of devices attached
HT845KV55555	device
emulator-5554	device

Normally, however, I’m not running adb directly, but indirectly via an Ant build. If I try, for example, to run the install target with multiple devices attached, adb is not happy:

jsankey@caligula:~/work/my-app$ ant install
Buildfile: build.xml
    [setup] Android SDK Tools Revision 6
    [setup] Project Target: Android 2.2

...

install:
     [echo] Installing /home/jsankey/work/my-app/build/MyAppActivity-debug.apk onto default emulator or device...
     [exec] error: more than one device and emulator

BUILD FAILED
/usr/local/java/android/platforms/android-8/ant/ant_rules_r2.xml:362: The following error occurred while executing this line:
/usr/local/java/android/platforms/android-8/ant/ant_rules_r2.xml:191: exec returned: 1

Total time: 1 second

The Ant build cannot guess which device to use by default, so it errors out. By digging into the Android Ant rules file, I found that the Ant builds support a property named adb.device.arg, which allows you to pass flags through to adb. For example, I can instruct the Ant build to install the application on the emulator as follows:

jsankey@caligula:~/work/my-app$ ant -Dadb.device.arg="-s emulator-5554" install
Buildfile: build.xml
    [setup] Android SDK Tools Revision 6
    [setup] Project Target: Android 2.2

...

install:
     [echo] Installing /home/jsankey/work/my-app/build/MyAppActivity-debug.apk onto default emulator or device...
     [exec] 266 KB/s (14446 bytes in 0.052s)
     [exec] 	pkg: /data/local/tmp/MyAppActivity-debug.apk
     [exec] Success

BUILD SUCCESSFUL
Total time: 6 seconds

There is, however, one sticking point. To run a test application via Ant, you can use the run-tests target. As of the latest SDK release, however, the run-tests target does not respect the adb.device.arg property. When I discovered this a couple of weeks ago, I raised an issue about it, and it was promptly fixed. Until the fix is released, though, a workaround is needed.

Luckily, adb supports another way to specify the device: via the ANDROID_SERIAL environment variable. This variable takes the same serial values as the -s flag, and being part of the environment is independent of how you end up running adb. To repeat my previous example, I just need to set the variable to the serial for my emulator:

jsankey@caligula:~/work/my-app$ export ANDROID_SERIAL=emulator-5554
jsankey@caligula:~/work/my-app$ ant install
Buildfile: build.xml
    [setup] Android SDK Tools Revision 6
    [setup] Project Target: Android 2.2

...

install:
     [echo] Installing /home/jsankey/work/my-app/build/MyAppActivity-debug.apk onto default emulator or device...
     [exec] 277 KB/s (14446 bytes in 0.050s)
     [exec] 	pkg: /data/local/tmp/MyAppActivity-debug.apk
     [exec] Success

BUILD SUCCESSFUL
Total time: 4 seconds

Presuming you have control of the environment in which adb is run, the ANDROID_SERIAL variable is probably your best bet for targeting a specific device.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • DZone
  • Ma.gnolia
  • Reddit
  • Simpy
  • Slashdot
  • StumbleUpon
  • Technorati

Leave a Reply