środa, 14 sierpnia 2013

Creating Android emulator v17 that support Google Maps v2

Few weeks ago we (my company) had been organizing a workshop for students. The topic of the workshop was Google Maps v2 for Android.

We usually work with devices, but for the workshop we could not assume  that everyone will posses the device which can run Google Maps.

When you run application in Android API 17 you will get the message that you need to Get Google Play services.

When running on the Google API 17 we get an empty map and in the logcat we can find.
W / EGL_emulation ( 1399): eglSurfaceAttrib not implemented
This was explained on some posts that for Google Maps OpenGL ES must be emulated.



Sometimes you get an information to update Google Play Services within an emulator.


I started researching the Internet/Stack Overflow for the solutions on the Google Map enabled emulator.
Seemed that several people tried this and there were contradicting reports.

Some blog posts say is impossible:
http://stackoverflow.com/questions/16478801/google-map-v2-on-android-emulator
http://stackoverflow.com/questions/14040185/running-google-maps-v2-on-android-emulator
http://stackoverflow.com/questions/14445093/how-to-show-google-map-v2-on-android-emulator

Some give some instructions to overcome the problem
http://nemanjakovacevic.net/blog/english/2012/12/06/how-to-make-android-google-maps-v2-work-in-android-emulator/
http://stackoverflow.com/questions/13691943/this-app-wont-run-unless-you-update-google-play-services-via-bazaar/13734937#13734937
http://umut.tekguc.info/en/content/google-android-map-v2-step-step
http://saleh360.blogspot.com/2012/12/android-running-google-maps-api-v2_12.html
http://stackoverflow.com/questions/17408688/google-map-v2-android-emulator

What was in common in most of them is that you need to install some APKs in the emulator to make Google Services to work.

This post that was the most influential, was this one
http://38911bytes.blogspot.de/2012/03/how-to-use-google-maps-api-in-android.html
it gave a nototion that you can modify the system.img.

I also found similar, a bit later
http://weezlabs.com/Blog/Post/customization-of-intel-android-emulator

I cannot quote the sites now but I also tried downloading a complete image of an emulator. Of course it did not work.

From many posts in the internet I collected that Google Maps need:
  • intel x86 emulator to emulate OpenGL ES. This will not run on the Google Api emulator which has only arm binaries.
  • the Google Play Services is some Service that resides in apk(s) that are on the Google Api emulator but not in Andoid emulator.

The idea that sparked in my mind was simply to combine both emulators into one. First I started pulling apk(s) from one emulator and trying to install on another. But some of the apps did not want to install and even if they did I did not wanted to distribute the complete avd image for the emulator.

The post 38911bytes blog suggested we can make a yaffs2 image from the live system and put it in the avd directory. This happened to work and if you are on linux as I am you can use the mkfs.yaffs2.x86 directly in your system.

Similar can be also found in android source code under external/yaffs2 but it requires long compilation, unless you know how to compile single repository of yaffs2. I don't so I had to wait some hours before I could use it.

Running the creation on the regular PC would be better solution as mkfs.yaffs2.x86 is very slow on emulator. I thaugth there must be a way to unpack system.img and yes this was true.

You can get this tool from here (source code and binary)
https://code.google.com/p/unyaffs/downloads/list

This can be found compiled also with a tool to pack image back
https://code.google.com/p/yafuse/downloads/list

Armed with those tools you can bind two system.img into one.
  1. Create the directory for the maps
    mkdir -p ~/tmp/maps/g17 ~/tmp/maps/a17
  2. Unpack the google api image into a g17
    unyaffs ~/android-sdk/add-ons/addon-google_apis-google-17/images/armeabi-v7a/system.img
  3. Unpack the android api image into a17
    unyaffs ~/android-sdk/system-images/android-17/x86/system.img
  4. Copy four apks from g17 directory to a17
    • GoogleLoginService.apk
    • GoogleServicesFramework.apk
    • Maps.apk
    • PrebuiltGmsCore.apk
  5. Make the system image again
    mkyaffs2image a17 ../system.img
  6. Create AVD
  7. The important bits are:

    • Target: Android API Level 17
    • CPU/ABI: Intel Atom (x86)
    • Use Host GPU
  8. Move system.img you created to the avd directory. In my case is
    mv system.img /home/made/.android/avd/new.avd/
    I have named the avd new. But the name is to your choice.
  9. You can start the emulator, now. If you need debugging I recommend to run this command
    emulator @new -verbose -show-kernel

Voila. The maps API seem to work!


I also had this error (but does not preven Maps API to be working).

emulator: Initializing hardware OpenGLES emulation support
emulator: ERROR: Could not load OpenGLES emulation library: lib64OpenglRender.so: cannot open shared object file: No such file or directory

You can do this
export LD_LIBRARY_PATH=/home/made/android-sdk/tools/lib:$LD_LIBRARY_PATH
of course substitute this with the correct path to the android sdk directory.

With that fix Maps work faster as OpenGL instead of software renderer is used.

Note that on the contrary to 38911bytes I do not copy maps.jar nor permissions file. I believe these step is necessary for Google Maps API v1. This does not hurt Google Maps API v2 but if you need Maps Api V1 you need copy com.google.android.map.xml to etc/permission and com.google.android.maps.jar to framework dirs from Google API system.img.

czwartek, 5 lipca 2012

Confitura 2012 review

Confitura is the biggest free conference for Java Programmers in Poland. It has always been a place to get enormous amount of inspiration and motivation to be a better programmer.

It was no different this year. Huge amount of geeks, great number of interesting companies promoting themselves, awesome presentations and everything of IT for free. As a wannabe Android Programmer I usually do not find Android related presentations but I treat confitura to make me up to date with current Java world.

What strikes me about confitura is that usually there are many contradictory opinions about this event. There are people who complain about it and some that praise it very much. I guess it depends on selection of presentations they chose.

This year my selection was a bit unfortunate for me I am afraid. First presentation I chose was Grzegorz Duda's From Busy To Effective Developer. I know Grzegorz from his great work on 33rd degree organization and I expected a top level presentation. I was a bit disappointed, might be for the high expectation. If you are intereseted not only in programming but also in becoming a greater developer probably you have heard most of the things mentioned in this presentation. What was good in that speech was the names of the tools Grzegorz is using. Unfortunately they were not on the slides and the names were not clearly heard (due to some echo in the place I was sitting). Grzegorz mentioned pommodoro technique which I tried to use some time ago and said that 25min session is too little for a programmer. That is interesting point of view. In overall I give 2 stars for this presentation.

The next presentation was Cezary Bartoszuk presentation about contracts. This presentation was the best during the whole day, in my opinion. The presenter was very convincing, looking  comfortable and passionate about the subject. The tools presented: CoFoJa and Yeti are probably worth trying in my projects. I am not stating this is the way we should do projects but I am interested to try contracts. 5 stars for this presentation.

Jakub Nabrdalik and Tomek Przybysz gave very promising presentation about other languages you can use with JVM. During TomTom developer days (a daily conference for TomTom Łódź employees) I had seen a presentation about Grails and was a bit better than this one. I think Jakub and Tomek tried to squeeze too much into the timespan they were given. At some point I had impression they are rushing too much. What I liked was a summary of paradigms in modern programming languages. 2 stars for them.

After lunch I chose Grzegorz Balcerek, but after few slides we escaped to Michał Bartyzel's retrospectives. We expected some talk about architecture or misuse of patterns in programming languages from Grzegorz but we got some Scala features instead. Michał is an experienced trainer and you could really see that on stage. The way he strengthen his speech with body language was really impressive. He also used a lot of metaphores which is a great way to explain things.
As far as the content is concerned this is again something you have probably heard of already if you are interested in becoming a A-class programmer.
What is worth mentioning was the idea of personal retrospectives and being consequent in applying it everyday. 4 stars for this presentation.

I was very interested what really CQRS is, as I heard the buzzword before but did not feel what exactly it is. After Maciej Próchniak's talk I would probably understand more but not yet feel very confident. Probably I need to learn a bit about that. Maciej was very enthusiastic and relaxed speaker. However I think they were places in that talk that were a bit boring. Good that Maciek mentioned that customer must be aware of applying CQRS pattern to a project (is not CRUD). 2 stars for this presentations.

Last but not least was Paweł Cesar Sanjuan Szklarz. Again I believe that presentation skills were decent but the content was not as interesting. As far as I understood Paweł tried to explain new way of building systems, which he invented himself. It was not using x-tier-architecture but plain code. I would expect to present on a conference a proven solution used by many clients instead of 4th revision on github used only by Paweł. Generally I would rank this as 1 star.

I would forgot about the closing keynote. Wojciech Seliga was offending lot of B/C-class programmers in his speech. Probably he motivated more his team than confitura attendees.
On the other hand Wojtek was right. I personally do not know many things that he mentioned as an elementary for a Java developer. Probably I have not been given an opportunity to use them in practice.

It seems that my selection was a bit unfortunate this year. Only 2 presentations were above a half of scale. But confitura is not only presentations. This is the place to meet other people, learn new buzzwords, see the creme de la creme of polish programmers. Plus one star for that.

Finally some words about the venue. It was a bit crowdy and hot, but the organization was perfect. Almost no queues (probably because I was late), food and beverages were in place. The lunch was tasty and for free. Plus one star.

Organizers also get one star for a slide about mobilization.pl - the conference about mobile technologies that will be held 22nd of September in Łódź. I am one of the organizers of this conference and I encourage to join this conference. The registration will be open a month before the conference starts.

Total grade for confitura is thus very high. This is the conference I would recommend for everyone. Everyone that wants to go a level up in his career.

Confitura is a role model for free confrerences that also mobilization.pl is pursuing for.


piątek, 16 grudnia 2011

Cracow.mobi review

Last week, I visited Cracow and its first edition of conference on mobile application developement.
I was delivering a presentation about Testing in Android (in Polish). It was my second try with this presentation.
The first time was during mobilization.pl conference in Łódź, which I also coorganized last October.

The event was held in conference centre of Technical University of Kraków: Kotłownia (boiling room) and GIL .
Registration was a bit crowdy but in a minute I got nice set of Android stickers and id. Some students came to me and said they liked the presentation in mobilization.pl despite the fact that examples (maven!) did not work.

Coffee was served downstairs but the place was not labelled properly I think so not many people knew it.
There was no food provided for atendees but I was stressed with my presentation so I did not care so much.

First day of the conference had two tracks (Android and iOS) held concurrently. I stayed in Android because my presentation was the 3rd.
The Kotłownia site was really great. The screen was big, there was also LCD screen for the presenter so speaker could see his slides without turning back on the attendees.
What is more the room had 2nd level being also equiped with a small screen and few rows of chairs for attendees.

The organizers already announced some changes in the agenda due to abscence of speaker (in iOS track) and then conference started.
The conference started strong. First Android speaker was Pawel Zieba and talked about sqlite. I liked the technical content he delivered with some minor exceptions to some presentation skills (sometimes too quiet). Pawel got lot of question from the public so it means it was interesting for many.
Next presentation was eagerly awaited by me. Konrad Malawski was talking about roboguice. I know what roboguice is, I even once aimed at presenting about it but never actually got into. Konrad made really good impression on me with his presentation. Roboguice seem to make code look better. The presenter answered smoothly real-life questions so I really believe he is using not only gives presentations about it.

I will not judge my own presentation. I am still not very happy about it, maybe next conference it will go smoothly. Again I had some problems with examples and multiscreens.
I need consider showing videos instead and not switching to eclipse.

After lunch there was a presentation from Jacek Laskowski who just started learning Android, half a year ago. Jacek is a person who inspires me and many people from JUGs in Poland. It was a pleasure to see Jacek presentation skills (great voice, good interaction with audience) and I think he made the most of few lines of code he presented.

Next presentation by applicake guy was about content synchronization. Unfortunately I haven't seen that fully so I am not able to judge it.

Next day seemed to be less rich in presentations for me but started strong with very inspiring speech by Łukasz Mikulski and games in our life.
Cool transitions (I guess thanks to Mac's keynote), embedded videos and real life examples made it good start of the day.
This speaker was late so before he started there was a really cool round of "introduce yourself" with everybody having a microphone to say few sentences about themselves. There was a bunch of interesting people representing startups or portals.
The agenda was already a mess so noone know at what time next presentation starts.

I moved to GIL to see the presentation I missed during mobilization.pl from Bartłomiej Zass from Microsoft. He is proffessional speaker and he confirmed that: technical problems were solved with grace, good interaction with attendees, no difficult questions. After lunch I come back to GIL to see presentations about phonegap. Krzysztof "Procek" Ścira was natural born speaker. It was smooth and he talked about practise giving many useful tips for people who like to start the adventure with phonegap. His presentation attracted only handful of people (due to problems with agenda I guess) and he treated this group with great respect and did very good presentation with focus on practical things (project setup etc.).

To sum up, I think that event was good but there is lot of to improve for the next edition.
I liked:
+ general idea :)
+ android stickers and t-shirt (I got 3 :) - as a speaker, for answering questions and for being mobiledeveloper.pl fan :))
+ meeting few people I knew before only from twitter
+ having a chance to see Jacek Laskowski in action and spare few words with him

I did not liked:
- agenda changes, moreover poorly advertised
- speakers that did not arrive (yes I know is not the fault of organizers, we faced the same during mobilization.pl)
- afterparty on the last day, should be on Friday

niedziela, 24 kwietnia 2011

Converting release keys to debug

Tests in android are like applications. They are organized into apks. They are installed along with application under test.
For security reasons they both require to be signed by the same keystore.

If you use different key for the application and the test you will get error:

Test run failed: Permission Denial: starting instrumentation ComponentInfo{net.retsat1.starlab.test/android.test.InstrumentationTestRunner} from pid=305, uid=305 not allowed because package net.retsat1.starlab.test does not have a signature matching the target net.retsat1.starlabjava.lang.SecurityException: Permission Denial: starting instrumentation ComponentInfo{net.retsat1.starlab.test/android.test.InstrumentationTestRunner} from pid=305, uid=305 not allowed because package net.retsat1.starlab.test does not have a signature matching the target net.retsat1.starlab


During development cycle keys generated by eclipse are usually used. When you are starting to think about release you are preparing the build signed with release key.

In eclipse there is no automatic way to sign for release, so you probably hand over this to ant script or do the signing by hand.

Afterwards if you are lucky your test that had previously run successfully on debug mode will be still passing in release mode. If for some reason this is not true you want to debug your test with eclipse.

When you want to run test(s) against your new build you find that signatures of the test and release apk mismatch.

In eclipse you can set a custom keystore from menu

Windows -> Preferences -> Android - > Build


This unfortunately leads to a problem as you eclipse does not accept release keystore with an error: Keystore was tampered with, or password was incorrect.

To convert release key to debug one that will be acceptable for eclipse, you need to import keystore into new debug keystore with keytool from jdk. This is done with the following command.

keytool -importkeystore -v -srckeystore release.keystore -destkeystore custom-debug.keystore -srcstorepass release-pass -deststorepass android -srcalias release-key -destalias androiddebugkey -srckeypass release-pass -destkeypass android


Of course substitute passwords and alias of source keystore with the one used in creation of release keystore.

wtorek, 29 marca 2011

Taking a screenshot in Android

There are plenty quite few decent methods for taking a screenshot in Android.

  • Monkey runner that comes with sdk 2.3 (works in 2.2 (checked) and earlier (assumed))
    http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html#SampleProgram
    This is pretty cool, python thing. I just wonder if that can be used within android with Android Scripting Engine. Definitely good choice for automated things like tests.
  • Reading framebuffer with an adb command
    adb pull /dev/graphics/fb0 screenshot.raw

    and processing this with some geeky commands. Might be impressive for your geekfriends but is not very simple to use.
    More about it you can read here here and there. The problem is that you have to count the buffer size, know the format of framebuffer and is not quite obvious.
  • Using android screenshot library maintained by polidea
  • Using ddms tool from sdk

    Pretty simple but you can't use it in an environment in automated, operatorless (no human involved) way.
  • Using a hierarchy viewer tool. With that you can take screenshots not only of the whole screen but also individual controls (views in android jargon).
  • Writing something around ddmlib. In fact all the tools above except ASL use ddmlib.
  • Last, but definetely not least is something by google itself. No surprise done on top of ddmlib.
    This tool is called screenshot and is in java. You can find that in sdk
    sdk/screenshot/src/com/android/screenshot/Screenshot.java.
    I am pretty sure you can compile it standalone with ddmlib as only dependency, but I had already built my sdk and it was compiled in

    android-source/out/host/linux-x86/bin/screenshot2
    and that simply works!
    ./screenshot2
    Usage: screenshot2 [-d | -e | -s SERIAL] [-l] OUT_FILE
    -d Uses the first device found.
    -e Uses the first emulator found.
    -s Targets the device by serial number.
    -l Rotate images for landscape mode.


Enjoy!

czwartek, 10 marca 2011

Mavenize existing android eclipse project

I have been working some time on android projects that try to use maven. We grew with the maven android plugin and maven/android eclipse plugin.
In this article I wanted to create guide how to mavenize existing android/eclipse project. During writing this post I discovered that few things have been different with new plugins (android or eclipse) and changed for better.

I used git to track what changes are being done by each steps described here to show the diff(s) and explain better what has happened.


  1. Create eclipse project for transition

    The project to show the mavenization process has been created with following parameters.

    Application name: MavenizeMe
    Package: net.retsat1.starlab.mavenize
    Activity: Me
    Sdk: 8

  2. Create android maven project from archetype
    https://github.com/akquinet/android-archetypes/wiki/android-quickstart-archetype

    mvn archetype:generate \
    -DarchetypeArtifactId=android-quickstart \
    -DarchetypeGroupId=de.akquinet.android.archetypes \
    -DarchetypeVersion=1.0.5 \
    -DgroupId=net.retsat1.starlab.mavenize \
    -DartifactId=mavenize-me

    To change sdk to 8 you need to answer 'N' for the first question and correct the default 7.

  3. Copy pom.xml to the project with android

  4. Import the project as maven project.

    When the project gets imported you will notice changes in .project and .classpath.

    .project shows that the project has new nature of maven nature.
    One of the builders is removed and instead we have maven builder.

                     </arguments>  
    </buildCommand>
    <buildCommand>
    - <name>com.android.ide.eclipse.adt.ApkBuilder</name>
    + <name>org.maven.ide.eclipse.maven2Builder</name>
    <arguments>
    </arguments>
    </buildCommand>
    </buildSpec>
    <natures>
    + <nature>org.maven.ide.eclipse.maven2Nature</nature>
    <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
    <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>

    I have been having lot of problems when apk builder was enabled. It did not go well with maven builder and I was getting some random errors during the build. I think the earlier versions of the plugin had not been removing apk builder and it clashed with maven very often.

    .classpath has a bunch of new entries
     -     <classpathentry kind="src" path="src"/>  
    - <classpathentry kind="src" path="gen"/>
    + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
    + <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
    - <classpathentry kind="output" path="bin"/>
    + <classpathentry kind="src" output="target/android-classes" path="gen">
    + <attributes>
    + <attribute name="optional" value="true"/>
    + </attributes>
    + </classpathentry>
    + <classpathentry kind="output" path="target/android-classes"/>


    Not sure why src has been removed. I reverted it back by rightclick on src and add to build path.

    There is a wide belief that eclipse files should not be committed to version control but should be generated for every developer on his own machine. In general I believe that is true but for android maven project this might be exception to the rule.
    In this case these files are already there :) What is more, mvn eclipse:eclipse generates something that does not work well as in case of regular java projects.

  5. Enabling ADT to run and debug.

    After cleaning the project I noticed that the project cannot be run with eclipse adt plugin. Could not find mavenize-me.apk!

    Maven does produce apk, but it has version number in the name./target/mavenize-me-1.0-SNAPSHOT.apk.

    At the same time ADT plugin expects the apk with the name as the project at the output folder.

    The solution is to either force maven to generate a project without a version information or copy generated apk to the location that adt expects. I used the second solution with the help of maven-ant-plugin.
     <plugin>  
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.6</version>
    <executions>
    <execution>
    <phase>package</phase>
    <configuration>
    <target>
    <property name="source"
    value="${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}" />
    <property name="destination"
    value="${project.build.directory}/classes/${project.name}.apk" />
    <delete file="${destination}" />
    <copy file="${source}" tofile="${destination}" />
    </target>
    </configuration>
    <goals>
    <goal>run</goal>
    </goals>
    </execution>
    </executions>
    </plugin>


  6. Fixing the source location

    The apk generated by maven does not contain anything except the resource so the process crashes on emulator. It does not see the activity class Me. The default maven for java code is src/main/java but adt plugin prefers the src directory.

    We can either setup maven to work with
     <sourceDirectory>src</sourceDirectory>  
    or move the src folder to the location that maven prefers to work with. I chose the latter.

    mkdir -p src/main/java
    git mv src/net/ src/main/java/

    And set the eclipse classpath to new location. First you need to remove src from the path and add it src/main/java
    .classpath will show the diff as follows
     -    <classpathentry kind="src" path="src"/>  
    + <classpathentry kind="src" path="src/main/java"/>


  7. Remove the builders

    I did not understand why we need other builders than maven and java so I removed ResourceBuilder and Precompiler from the .project.

         </projects>  
    <buildSpec>
    <buildCommand>
    - <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
    - <arguments>
    - </arguments>
    - </buildCommand>
    - <buildCommand>
    - <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
    - <arguments>
    - </arguments>
    - </buildCommand>
    - <buildCommand>
    <name>org.eclipse.jdt.core.javabuilder</name>
    <arguments>
    </arguments>


    It turned out when I added new id to the main.xml that it is not visible in net.retsat1.starlab.mavenize.R. The eclipse project does not compile and as a result run button does not work. Also the project reports errors. Maven on the other hand successfully compiles the project.

    The id is generated in
    target/generated-sources/r/net/retsat1/starlab/mavenize but not in gen folder by adt. No wonder, because I removed the builder responsible for that. But if it is generated in the r directory we do not need gen folder. It must be on the build path. Deleting gen will cause adt to complain about missing problem so I needed a nifty way to deceive eclipse. This way is to create a linked folder name gen pointing to the r folder. We use eclipse variable for that


    PROJECT_LOC/target/generated-sources/r


     +        <link>  
    + <name>gen</name>
    + <type>2</type>
    + <locationURI>PROJECT_LOC/target/generated-sources/r</locationURI>
    + </link>



  8. The maven way

    At this moment I had source in the standard maven but still assets and res folders at root that does not look like a standard maven. I am not sure where would be the correct place in maven for them but chose src/main/android-assets and src/main/android-res. To make adt happy I did the same trick as with link to generated sources.

     +        <link>  
    + <name>assets</name>
    + <type>2</type>
    + <locationURI>PROJECT_LOC/src/main/android-assets</locationURI>
    + </link>
    + <link>
    + <name>res</name>
    + <type>2</type>
    + <locationURI>PROJECT_LOC/src/main/android-res</locationURI>
    + </link>


    The defaults in maven-android-plugin are the same as for adt plugin so is necessary to adjust those paths.

     -                    <assetsDirectory>${project.basedir}/assets</assetsDirectory>  
    - <resourceDirectory>${project.basedir}/res</resourceDirectory>
    + <assetsDirectory>${project.basedir}/src/main/android-assets</assetsDirectory>
    + <resourceDirectory>${project.basedir}/src/main/android-r</resourceDirectory>


  9. The maven project

    In those steps I achieved the project which is compiled solely by maven. The project is also using adt plugin for running and debugging so creates similar experience for the developers accustomed to adt.

    I am sure this is rather lengthy operation to convert to maven project and I had not discoverd many problems that bigger android maven projects may have on such trivial example. I have not considered a project with android tests.

    Another drawback of this setup is that Maven as a project builder is not very convenient. Is much slower than adt and also does not support incremental builds perfectly. In the background maven compiler is invoked constantly eventough there are no changes ins the source code. That might be little annoying.

    The pros for such setup is for sure the dependency management that maven may give you.
    On top of that also your continuous integration system will be more than happy to receive maven project and should generate the same artifact(s) as on developers workstations. I do not like when developers use different method of building the projects(on their workstation) than the official build does. Is often the case of works for me only or send my build to the customer scenario.

środa, 9 marca 2011

Getting started with Android & Maven

Is hard to imagine a project that is expected to deliver something without having a build script that automates the process. Batch/shell script is a primitive example but ant and maven are well established industry standards for build solutions. Maven scope is slightly bigger than that but main part of maven is for building.

Android folks have selected ant as their choice. In the sdk you can find ant examples (platforms/android-8/ant) and by using android create project command you can get a skeleton of android project that is built by ant.

Maven is widely considered as next step in evolution after ant so no wonder that many people start asking question if there is a support for android in maven.

Android maven plugin is the answer they look for. To get started there are few ways to do it

When analyzing samples, at the first glance you will notice that standard maven directory layout is not preserved. The reason for that is that maven android plugin does not want to go into the way of android development tools (adt) layout. People accustomed to maven will find it slightly odd.
To work with eclipse you obviously need m2eclipse plugin and maven-android-integration plugin. You can find that with eclipse marketplace directly from eclipse.
After plugins are installed the next thing you do is to import the project in eclipse (Import -> Existing maven project), it does not work on start but after clean or two you have a compilable maven + android project.

When project is imported in eclipse it will be treated as maven project but also will have android nature. This allows the developer to use a Run As Android Application (and Debug).


When you go to a builders configuration page (Projects -> Properties -> Builders) you should see 4 builders, 2 from adt (android resource builder and precompiler) and java and maven builder. I don't think that the 2 former are really necessary for the project. At least disabling them does not cause anything noticeably bad.

To learn what is available from the android plugin use help:describe goal.
mvn -Dplugin=android help:describe -Dfull=true This would display a lengthy list with the targets you may use along with the configuration xmls that can be placed in the pom.xml in plugin configuration.

Most important goals are
  • android:apk - to create android pakcage
  • android:deploy - to deploy on emulator/device
  • android:emulator-start

My own opinion



I must admit I was never a fan of maven. Mainly because mobile projects I was involved in where rather small, having no dependencies and mostly ant based. When I tried learn on my own I was put off by the conventions imposed by maven. My prejudice towards maven would last probably longer hadn't been I forced to use maven. Then I gradually discovered the power of auto dependency management and the benefits of conventions.


As android is concerned I still find some clashes but the maven plugin is strongly developed. Mailing list is active, development is active and new features arrive at good pace (recently apklib).
Still have not dwelt very deeply in android maven development so I cannot say is industry ready yet or not but the future looks promising.