Archive
Tags
android (3)
ant (2)
beautifulsoup (1)
debian (1)
decorators (1)
django (9)
dovecot (1)
encryption (1)
fix (4)
gotcha (2)
hobo (1)
htmlparser (1)
imaplib (2)
java (1)
json (2)
kerberos (2)
linux (7)
lxml (5)
markdown (4)
mechanize (6)
multiprocessing (1)
mysql (2)
nagios (2)
new_features (3)
open_source (5)
optparse (2)
parsing (1)
perl (2)
postgres (1)
preseed (1)
pxe (4)
pyqt4 (1)
python (41)
raid (1)
rails (1)
red_hat (1)
reportlab (4)
request_tracker (2)
rt (2)
ruby (1)
scala (1)
screen_scraping (7)
shell_scripting (8)
soap (1)
solaris (3)
sql (2)
sqlalchemy (2)
tips_and_tricks (1)
twitter (2)
ubuntu (1)
vmware (2)
windows (1)
zimbra (2)

Wouldn't it be nice to write android applications in Scala? And wouldn't it be even better to build these applications with ant just like can be done with Java? Well, it is possible and I've taken out all of the frustration of figuring out how for you! No Eclipse required!

We do this by altering the ant build rules in the android SDK. In the android SDK directory, replace the content of platforms/?/templates/android_rules.xml with the content linked below.

Now we have to copy a few jars to the tools/lib directory of our SDK.

Copy scala-compiler.jar and scala-library.jar from the lib directory of the Scala distribution.

Copy proguard.jar from the lib directory of the Proguard distribution. Proguard is used to create a single jar with only the class files your application uses.

We are all set to build android applications with Scala now. Let's go through one for android-2.0 to test.

Create a new android project:

$ android create project --package com.example.helloscala --activity HelloScala --target android-5 --path HelloScala

In this new project, remove src/com/example/helloscala/HelloScala.java and create src/com/example/helloscala/HelloScala.scala with the following contents:

package com.example.helloscala

import _root_.android.app.Activity
import _root_.android.os.Bundle

class HelloScala extends Activity {
  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)
  }
}

From the root of the project run ant debug to build a test apk. Output will look similar to this:

Buildfile: build.xml
    [setup] Project Target: Android 2.0
    [setup] API level: 5
    [setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.

-compile-tested-if-test:

-dirs:
     [echo] Creating output directories if needed...
    [mkdir] Created dir: /home/tlesmann/src/android/HelloScala/gen
    [mkdir] Created dir: /home/tlesmann/src/android/HelloScala/bin/classes

-resource-src:
     [echo] Generating R.java / Manifest.java from the resources...

-aidl:
     [echo] Compiling aidl files into Java classes...

compile:
    [javac] Compiling 1 source file to /home/tlesmann/src/android/HelloScala/bin/classes
   [scalac] Compiling 1 source file to /home/tlesmann/src/android/HelloScala/bin/classes

proguard:
 [proguard] ProGuard, version 4.4
 [proguard] Reading program directory [/home/tlesmann/src/android/HelloScala/bin/classes]
 [proguard] Reading program directory [/home/tlesmann/src/android/HelloScala/libs]
 [proguard] Reading program jar [/home/tlesmann/src/android/android-sdk-linux/tools/lib/scala-library.jar] (filtered)
 [proguard] Reading library jar [/home/tlesmann/src/android/android-sdk-linux/platforms/android-2.0/android.jar]
 [proguard] Note: scala.xml.include.sax.Main$ calls '(org.xml.sax.EntityResolver)Class.forName(variable).newInstance()'
 [proguard] Note: there were 1 class casts of dynamically created class instances.
 [proguard]       You might consider explicitly keeping the mentioned classes and/or
 [proguard]       their implementations (using '-keep').
 [proguard] Note: You're ignoring all warnings!
 [proguard] Preparing output jar [/home/tlesmann/src/android/HelloScala/bin/classes.min.jar]
 [proguard]   Copying resources from program directory [/home/tlesmann/src/android/HelloScala/bin/classes]
 [proguard]   Copying resources from program directory [/home/tlesmann/src/android/HelloScala/libs]
 [proguard]   Copying resources from program jar [/home/tlesmann/src/android/android-sdk-linux/tools/lib/scala-library.jar] (filtered)

-dex:
     [echo] Converting compiled files and external libraries into /home/tlesmann/src/android/HelloScala/bin/classes.dex...
     [echo]

-package-resources:
     [echo] Packaging resources
 [aaptexec] Creating full resource package...

-package-debug-sign:
[apkbuilder] Creating HelloScala-debug-unaligned.apk and signing it with a debug key...
[apkbuilder] Using keystore: /home/tlesmann/.android/debug.keystore

debug:
     [echo] Running zip align on final apk...
     [echo] Debug Package: /home/tlesmann/src/android/HelloScala/bin/HelloScala-debug.apk

BUILD SUCCESSFUL
Total time: 10 seconds

You should take notice that ant still builds java, the XML generated sources in the case. Let's try out our new apk. If you need to create an avd for the android 2.0 platform, do so with the following command:

$ android create avd --target android-5 --name android-5

And start it up:

$ emulator -avd android-5

Finally, install your apk:

$ adb install bin/HelloScala-debug.apk

You may have to run the preceding command twice, once to connect to the emulator and again to install. After that, you should be able to run the application from the emulator and see the following:

Scala on Android screenshot

Posted by Tyler Lesmann on December 4, 2009 at 10:03 and commented on 1 time
Tagged as: android ant scala

With the announcement of the Android Scripting Engine, I had to check it out, what with the ability to code python on the G1. It has one large inconvenience at the moment. There is no built in way to use scripts on the SD card. I have a workaround for the time being. With the following script, which runs with ASE, you will be able to import scripts from the ase folder of your SD card into ASE's normal script directory.

import android
import os
import shutil

src = '/sdcard/ase'
dst = '/data/data/com.google.ase/scripts'

droid = android.Android()
for file in os.listdir(src):
    shutil.copy(os.path.join(src, file), dst)
    # Interesting permissions on Android
    os.chmod(os.path.join(dst, file), 0666)

droid.makeToast('Import Complete')

Note that you will be typing this into your Android device through ASE. The last script you will have to do that way. You will have to close and reopen ASE before the scripts appear.

Posted by Tyler Lesmann on June 10, 2009 at 11:56
Tagged as: android fix python

Google has put a lot of work into their Android platform, but their non-Eclipse development instructions could use some work. Just trying to build their Hello, Android fails if you follow their notes to the letter. You'll get this error or similar:

[tlesmann@kimiko HelloAndroid]$ ant
Buildfile: build.xml

dirs:
     [echo] Creating output directories if needed...

resource-src:
     [echo] Generating R.java / Manifest.java from the resources...

aidl:
     [echo] Compiling aidl files into Java classes...

compile:
    [javac] Compiling 2 source files to /home/lethal/src/android/HelloAndroid/bin/classes
    [javac] Compliance level '1.4' is incompatible with target level '1.5'. A compliance level '1.5' or better is required

BUILD FAILED
/home/tlesmann/src/android/HelloAndroid/build.xml:140: Compile failed; see the compiler error output for details.

Total time: 1 second

I was completely at a loss with this error and all the pages I found on Google were worthless. I'm hoping to change that with this post. The problem is that Sun's javac has a compliance level of 1.4 by default. This can be changed with a command-line argument of -1.5. To get ant to use this argument when compiling, you have to edit the build.xml like so:

<!-- Compile this project's .java files into .class files. -->
<target name="compile" depends="dirs, resource-src, aidl">
    <javac encoding="ascii" target="1.5" debug="true" extdirs=""
            srcdir="."
            destdir="${outdir-classes}"
            bootclasspath="${android-jar}">
        <compilerarg value="-1.5"/>
        <classpath>
            <fileset dir="${external-libs}" includes="*.jar"/>
        </classpath>
     </javac>
</target>

Add the line, <compilerarg value="-1.5"/>, within the javac element and ant will properly build the Hello, Android application. I'm surprised that the activitycreator program does not do this for you as Google advises you to use Sun's JDK.

I hope I've helped you avoid the frustration I suffered solving this silly issue.

NOTE: You no longer have to do this with the release of the 1.5 SDK! Just install Sun's Java and it will build without a problem.

Posted by Tyler Lesmann on December 6, 2008 at 7:08 and commented on 3 times
Tagged as: android ant fix gotcha java