CALL +44 (0)20 7183 3893
Blog

Friday 21 January 2011

Use your Android to control AWS

There are two ways you can use the AWS API from your Android-powered device: using the Java SDK or, alternately, using the RESTful API. However, The AWS Java SDK for the Android (Beta) is a relatively recent development, and does not yet support accessing, monitoring, and manipulating Amazon EC2 instances.

Using the RESTful API to painstakingly build this functionality is probably not worth it, as the AWS SDK for Android is likely to include it in the foreseeable future, at which time you’ll probably have to migrate all of your code over. But if you can’t wait, there is a way to get the AWS Java SDK to play with your Android.
The principal reason why you can’t use the AWS Java SDK out-of-the-box on your Android device is the AWS SDK’s use of the Streaming API for XML (STaX), which is in the javax namespace. The Dalvik VM used on the Android does not include the whole Java stack, principally to conserve space. Additionally, as a developer, you are not, by default, allowed to bundle in libraries using the java or javax namespaces into your application - for good reason; as your application can potentially end up incompatible with future versions of Android that may include the selfsame library.\
So, if you try to include the AWS SDK JAR and all of its dependencies, including the STaX API, into your application, you will be faced with the following error upon compilation
[2010-10-24 14:11:43 - ElasticDroid]
Attempt to include a core class (java.* or javax.*) in something other
than a core library. It is likely that you have attempted to include
in an application the core library (or a part thereof) from a desktop
virtual machine. This will most assuredly not work. At a minimum, it
jeopardizes the compatibility of your app with future versions of the
platform. It is also often of questionable legality.
[...]
But if you really want to do it (you do, don’t you?!), there’s a workaround. Before I describe the workaround, let me first make the caveats of this approach clear:
  • You could be running the risk of having your application fail to work with a future version of Android (you’re fine with Gingerbread).
  • You won’t be able to use the ADT builder on Eclipse. You will have to use Ant.
  • You may need to change your build file every time there is a new Android SDK, as Google often change the build.xml templates without documenting it.

So, the workaround! You can use the --core-library option to force the Android build system to allow you to accept the STaX JAR into your application. The rest of this article describes how you can do this.

Assumptions

We make the following assumptions here:
  • Your source code is in the src/ directory.
  • Your external libraries (JARs) are in the lib/ directory.
  • You are using revision 8 of the Android SDK.
Generate build.xml
To generate a build.xml file for your project, fire up a terminal, and type
cd path/to/project
android update project -p . --target android-8
This should create/update the files:
  1. default.properties
  2. local.properties. Warning: do not commit this file into version control; this includes the path to the location of the Android SDK on your machine!
  3. build.xml
Modify build.xml
The build.xml file created by default imports most stuff from a template file. The easiest way to customise your build.xml file is to copy over the contents of the template file into your newly created file.
To do so,
  1. Look for the end of the section setup; marked
  2. Change to read
  3. Open the template file in the Android SDK using your favourite text editor.
    1. WARNING: There are several different template files lying about in the Android SDK folder. Some of them will cause your ant build to die a miserable NullPointerException death. This took me hours to figure out!
    2. For SDK r08, the file is:

path.to.android.sdk/tools/ant/main_rules.xml
  1. make sure jar.libs.dir is set to the directory containing your AWS JAR. I.e., you should have the following line in your code:
  2. Now, this step is the nub! Add the --core-library option into the dex-helper macrodef. Additionally, add a fileset directive to make sure your JAR files are packaged in

  <macrodef name="dex-helper">
<element name="external-libs" optional="yes" />
<element name="extra-parameters" optional="yes" />
<sequential>
<echo>
Converting compiled files and external libraries into ${intermediate.dex.file}...
</echo>
<apply executable="${dx}" failonerror="true" parallel="true">
<arg value="--dex" />
<arg value="--core-library" />
<arg value="--output=${intermediate.dex.file}" />
<extra-parameters />
<arg line="${verbose.option}" />
<arg path="${out.dex.input.absolute.dir}" />
<fileset dir="${jar.libs.absolute.dir}" includes="*.jar" />
<path refid="android.libraries.jars" />
<external-libs />
</apply>
</sequential>
</macrodef>
  1. Optional: Scroll up to the top of build.xml and set debug as the default build target.
Test your new build script

If you have an Android device, plug it in and type ant install into the terminal. This should then install the Android app that is using the AWS SDK on to your device.

Alternately, you can fire up an emulator (sort of) quickly by typing:
emulator -avd YourEmuName -timezone "Europe/London" -no-boot-anim

To learn how to create an emulator device, please see Android’s documentation.

Finally, if you’re looking for a working example of this hack, take a look at ElasticDroid (http://code.google.com/p/elastic-droid).

No comments:

Post a Comment

Pontus is ready and waiting to answer your questions