Android Scala Setup Tutorial - aagahi/spotmint-android GitHub Wiki
Android Scala Setup Tutorial
Install Android SDK
http://developer.android.com/sdk/index.html
And launch
./tools/android
And download Google API 7 and 10 bundle (we target API 7 but we'll use emulator with API 10 as the emulator doesn't work correctly with API 7).
Setup ENV var (for example in my case it will be $HOME/works/android-sdk).
export ANDROID_HOME=$HOME/works/android-sdk
Get android deployer
git clone git://github.com/mosabua/maven-android-sdk-deployer.git
Assuming you have android platform 2.1 and 2.3.3 installed in your sdk install the artifact using:
mvn install -P 2.1
mvn install -P 2.3.3
Follow getting started instruction from sbt android-plugin getting-started
Update the project/build.scala settings
val settings = Defaults.defaultSettings ++ Seq (
name := "SpotMint",
version := "0.1",
versionCode := 0,
scalaVersion := "2.8.2",
platformName in Android := "android-7",
resolvers ++= Seq( "Local Maven Repository" at "file:///Users/alag/.m2/repository/" )
)
We use scala 2.8.2 for many reasons but mostly for its small footprint.
Now specify local repo for maps.
Still in build.scala update dependencies:
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "1.7.RC1" % "test",
"com.google.android.maps" % "maps" % "7_r1" % "provided" )
)
maps is provided since it is should be on device.
And finally disable proguard for emulator build (we'll setup an emulator with scala jars embedded so you should bypass proguard stage for faster build process)
val proguardSettings = Seq (
useProguard in Android := false
)
You should enable proguard when you build your app for device (or market release) or if you don't want to run your app on emulator with custom ramdisk (see later).
When testing maps with your project you need to get an "debug" apiKey. See Google MapKey.
Update src/main/res/layout/main.xml
file with your apiKey.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="the API key"
/>
</RelativeLayout>
Remember that you will need to use a different API Key for market publication process.
Update AndroidManifest.xml
<application
android:icon="@drawable/android:star_big_on"
android:label="@string/app_name"
android:debuggable="true">
<uses-library android:name="com.google.android.maps" />
<activity android:label="@string/app_name" android:name=".MainActivity" android:launchMode="singleInstance" android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
As you can see we added <uses-library android:name="com.google.android.maps" />
and <uses-permission android:name="android.permission.INTERNET" />
required for app using maps.
List all your android target:
$ANDROID_HOME/tools/android list
Create an emulator image for API10 (I had some problem with API7 so I recommend 10)
$ANDROID_HOME/tools/android create avd -n API10 -t 4
(in my case -t 4 is API10).
Inspired from http://zegoggl.es/2011/07/how-to-preinstall-scala-on-your-android-phone.html
Install https://github.com/jberkel/android-sdk-scala and make sure you have
export ANDROID_SDK_ROOT=$ANDROID_HOME
Edit vi ./bin/createdexlibs
and ./bin/createramdisks
And adjust platform-tools path:
DX_LIST=`find $ANDROID_SDK_ROOT/platform-tools/ -name dx | sort -r`
Run ./bin/createdexlibs
Now create a custom ramdisk: ./bin/createramdisks
And boot up the emulator:
$ANDROID_HOME/tools/emulator -avd API10 -no-boot-anim -ramdisk ~/.android/avd/API10.avd-custom/ramdisk.img
Get device identifier:
$ANDROID_HOME/platform-tools/adb devices
In my case it is "emulator-5554"
Now create the scala jar folder on ramdisk:
$ANDROID_HOME/platform-tools/adb -s emulator-5554 shell mkdir -p /data/framework
And push the scala jars:
for i in configs/framework/*.jar; do $ANDROID_HOME/platform-tools/adb -s emulator-5554 push $i /data/framework/; done
And now reboot the emulator.
Use logcat if required:
$ANDROID_HOME/platform-tools/adb -s emulator-5554 logcat
Now you're ready to use sbt and deploy on the running emulator using sbt command:
~ android:start-emulator
You can get the emulator log using logcat adb command:
$ANDROID_HOME/platform-tools/adb -s emulator-5554 logcat
Also you can update the GPS position using telnet command on emulator such as:
> telnet localhost 5554
> geo fix -121.45356 46.51119 4392
In case you want to run your app on a device you can use https://github.com/scala-android-libs/scala-android-libs. It will require you to root your device but again, will save you tons of times during the building process avoiding the proguard stage.
If you use a Nexus One for dev check this link: http://forum.xda-developers.com/wiki/Nexus_One/Guides_%26_Tutorials#Root - in my case, having my N1 running on 2.3.6, I used the 2/ case (recovery-RA-passion-v2.2.1.img + su-2.3.6.1-ef-signed.zip) and had a problem with Froyo SuperUser tools (at recovery stage, I had to deactivate the signature check, install SuperUser zip, and then REACTIVATE the signature check). Also when installing the scala libs, superuser asks you root access for every command and you have to approuve all requests til the end.
If you're using an API7 ramdisk, you won't get network connectivity, I dont know exactly why.
If you use Scala 2.9.1 (on the emulator or a device) it seems that you might get a "LinearAlloc exceeded capacity" error/crash. This can probably be solved by with some dex parameters or image customization, see http://www.netmite.com/android/mydroid/2.0/dalvik/docs/embedded-vm-control.html. Also using scala 2.8.2 seems to be an appropriate workaround right now considering smaller build package generated. Scala 2.10.x seems to fix this problem (see SI-4620). If you're using a rooted device with scala-android-libs, you might also need to install scala-2.8.x dexed afterwards (using android-sdk-scala tools) instead of 2.9.1.
To use sbt as Idea plugin with android you can setup the env var as such
launchctl setenv ANDROID_HOME $ANDROID_HOME