Friday, 14 September 2012

Android + Scala + IntelliJ on Ubuntu For Dummies

Please use the instructions in this link instead:

So far I have realized that wikis matter! Nobody wants to repeat the same thing twice and the more easier the wiki the faster you get where you want.
The faster you get where you want the higher the chances you will win a new “customer” (developer) working on your technology than the other!
I like as many others, solving real engineering problems, like how to get meaningful results from a rating system or how to create a beautiful animation with the tools being provided or even how to model a protocol for interaction among my users.
All the other stuff, how to setup servers, get the libraries working etc. are boring!

One challenging feat is to get an android project work with scala!
So let me walk you through this tedious task!

Please note the versions for each tool I use.
For starters I am using the java version 1.7.0_09
Install these libraries in ubuntu if they are missing:
sudo apt-get install lib32ncurses5 lib32stdc++6

-Download and setup the android sdk. I have downloaded all versions from 1.5 (API 3) to 4.1 (API 16). I will not go into further details on this. There are many tutorials and the official guide is a good place to start:

We are going to need the android home path in an enviroment variable. So let's set a persistant enviroment variable for the current user

gedit ~/.pam_environment
and now append this: ANDROID_HOME=<the path of the android sdk>

Now let's grab the sbt tool. We could have used this repository and then do a sudo apt get update and sudo apt get sbt to get the sbt easily but this returns an older version.

We would rather have a manual installation of sbt.
Find the “Unix” section in the above link and download sbt-launch.jar and place it in ~/bin
Currently this is version 0.12.2
Then create an sbt file:
gedit ~/bin/sbt

write this line inside:

java -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -jar `dirname $0`/sbt-launch.jar "$@"

and make script executable:
chmod u+x ~/bin/sbt

For github templates you need the giter8 tool. So execute:
curl | sh
and then execute:
cs n8han/giter8

Now I use the g8 to get an android app template from jberkel:
g8 jberkel/android-app

There are some questions for you to setup. Currently I leave everything to default.
Which means:
Scala version: 2.9.2
If you feel more adventurous try the (non-stable) scala version 2.10.0-RC1 which is a little faster
Android API: 10 (2.3.3)
scalatest_version: 1.8.
Set useProguard to true.
Android devices do not have scala library inside and including in the package will make the .apk too large!
Proguard will only keep these parts of the library that you will use ;)

Before you run sbt:
We need to make an adjustment for the currently compatible sbt with the android-plugin.
Go inside the folder of the new android application e.g.
cd my-android-project/
and execute:
gedit project/
and insert this line:

Below at the command android:package-debug there were some warnings like:
trouble processing: bad class file magic (cafebabe) or version (0033.0000)
...while parsing my/android/project/R$id.class

That is why we follow this:
Android does not work with java bytecode of java 7 so you will need to work with java 6.
So you will need to add some configuration to the autogenerated Build.scala file of sbt:
gedit project/Build.scala

and inside there place at the beginning of settings inside the Seq( ) the line:
javacOptions ++= Seq("-source", "1.6", "-target", "1.6"),
scalacOptions ++= Seq("-deprecation", "-unchecked"),
and inside the proguardSettings insert after “useProguard in Android := true” this statement:
proguardOption in Android :=
      """-keep class scala.Function1
        |-keep class android.bluetooth.BluetoothDevice {
        | *** fetchUuidsWithSdp(...);
        | *** getUuids(...);

You also need to change the plugins.sbt file:
gedit project/plugins.sbt
and replace contents with these lines:
resolvers += Resolver.url("scalasbt releases", new URL(""))(Resolver.ivyStylePatterns)
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.2.0") 
addSbtPlugin("org.scala-sbt" % "sbt-android-plugin" % "0.6.2")
remember each .sbt files seperates each statement by an extra empty line

Inside the same folder execute:
sbt 'gen-idea no-classifiers' compile

and then go to the sbt interactive mode console:

Inside the console execute:

Now you can try to start an android emulator: android:emulator-start <my_avd>  # use <tab> to get a list of avds
android:emulator-start android2_1

after the emulator is fully started execute the android app like that:

Or you can try using a real device which is usually better since it is faster and nicer than an emulator

You must see the hello world application :)

Now a few days or a few week pass full of coding...

Finally you have something ready and you want to upload it on the market []

First inside sbt execute:

Yeah I think you got it right. This will create an .apk file inside target folder.

This file need a little bit processing before uploading on google play.

I omit referring how to create your own unique keystore file because there are many other tutorials who cover that and it is an one time thing!

First signing with jarsigner:

jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore <keystore file path> <apk file path> <your alias>

this will prompt you for the keystore password and the keypass.

the above command changes the .apk file itself and does not generate a new file. You can verify that with this command:

jarsigner -verify <apk file path>

Then you need to zipalign it:
~/android-sdk-linux/tools/zipalign -v 4 <apk path> <new aligned apk path>

This apk is now ready to be uploaded out in the wild !!

Note a few facts:
You must not write android version name and android version code as arguments inside AndroidManifest.xml
Rather you set these values inside Build.scala:
android:versionCode inside xml corresponds to -> versionCode attribute of Build.scala
same way android:versionName -> version

Now get out there and create a mobile application who offers real value ..or fun!
Author: George Pligor

Applied Ideas Copyright © 2010
George Pligor - Stergios