Introducing Android Scripting Environment

Monday, June 8, 2009

The Android Scripting Environment (ASE) brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreters directly on the Android device. These scripts have access to many of the APIs available to full-fledged Android applications, but with a greatly simplified interface that makes it easy to:

  • Handle intents
  • Start activities
  • Make phone calls
  • Send text messages
  • Scan bar codes
  • Poll location and sensor data
  • Use text-to-speech (TTS)
  • And more

Scripts can be run interactively in a terminal, started as a long running service, or started via Locale. Python, Lua and BeanShell are currently supported, and we're planning to add Ruby and JavaScript support, as well.

Scripts can be edited directly on the phone.

The script manager displays available scripts.

Scripts can be launched interactively or as background services.

Interactive terminals can be started for interpreters that support it.

Scripts can use the Android UI to get user input.

You may ask, why write scripts instead of real Android applications? Admittedly, Android's development environment makes life pretty easy, but you're tied to a computer to do your work. ASE lets you develop on the device itself using high-level scripting languages to try out your idea now, in the situation where you need it, quickly. Have a look at the following example Lua script to see for yourself:

--Placing the phone face down will disable the ringer. Turning it face up again will enable
--the ringer.
require "android"
android.sleep(1) --Give the sensors a moment to come online.
silent = false
while true do
s = android.readSensors()
facedown = s.result and s.result.zforce and s.result.zforce > 9
if facedown and not silent then
android.vibrate() --A short vibration to indicate we're in silent mode.
silent = true
elseif not facedown and silent then
silent = false

Here's another useful script, this time in Python.

"""Say chat messages aloud as they are received."""

import android, xmpp

_SERVER = '', 5223

class SayChat(object):
def __init__(self):
self.droid = android.Android()
username = self.droid.getInput('Username')['result']
password = self.droid.getInput('Password')['result']
jid = xmpp.protocol.JID(username)
self.client = xmpp.Client(jid.getDomain(), debug=[])
self.client.RegisterHandler('message', self.message_cb)
if not self.client:
print 'Connection failed!'
auth = self.client.auth(jid.getNode(), password, 'botty')
if not auth:
print 'Authentication failed!'

def message_cb(self, session, message):
jid = xmpp.protocol.JID(message.getFrom())
username = jid.getNode()
text = message.getBody()
self.droid.speak('%s says %s' % (username, text))

def run(self):
while True:
except KeyboardInterrupt:

saychat = SayChat()

These scripts demonstrates several of the available APIs available for both Lua and Python. It is intended to be run as a service and silences the ringer when the phone is placed face down. For some scripting languages, like BeanShell, it's possible to access Android's Java API directly. To simplify things, ASE provides the AndroidFacade class. For other languages, like Python and Lua, the API is made available via JSON RPC calls to a proxy. Naturally this means that only the part of the API which has been wrapped by the AndroidFacade and AndroidProxy are available to cross-compiled interpreters like Python and Lua. Thankfully, both AndroidFacade and AndroidProxy are simple to extend.

If you'd like to give ASE a try, it's not yet published to the Market, but will be soon. You can download the latest APK from our project page. Some sample scripts and documentation are also included there to help you get started. We always love to hear what you think, so please send us feedback or ask your questions in the ASE discussion group.