Programming on the Android mobile platform is, generally-speaking, a Java-based affair. This talk introduces the Scripting Layer for Android(SL4A) project by Damon Kohler and the Python for Android(Py4A) project, both of which work together to provide a Python interpreter environment for the Android platform. I will talk about the history, background and architecture and design of these projects, the current status, and what to expect in the near future. There will be a demo in this talk, which is inspired by the Cellbots project. In this demo, I show how a robot based on the Arduino open source hardware platform can be manipulated using the an Android mobile phone, and the open source projects discussed during the talk.
9. Simple Program in Java
package com.spodon.pycon;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.Toast;
public class Demo extends Activity {
private EditText mEditText = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Hello!");
builder.setMessage("What is your name?");
mEditText = new EditText(this);
builder.setView(mEditText);
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(Demo.this, "Cancelled", Toast.LENGTH_SHORT).show();
}
});
...
9
Friday, June 10, 2011
10. Simple Program in Python
import android
droid = android.Android()
name = droid.getInput("Hello!", "What is your name?")
droid.makeToast("Hello, %s" % name.result)
• Java program: 35 SLOC
• Equivalent Python program: 4 SLOC
10
Friday, June 10, 2011
11. Android module
import android
droid = android.Android()
name = droid.getInput("Hello!", "What is your name?")
droid.makeToast("Hello, %s" % name.result)
• Exposes android functionality via an
Android() object.
• Talks to a service called SL4A (Scripting
Layer for Android).
11
Friday, June 10, 2011
12. Invoking functionality
import android
droid = android.Android()
name = droid.getInput("Hello!", "What is your name?")
droid.makeToast("Hello, %s" % name.result)
Python Interpreter Android
functionality exposed
via RPC methods
android.py
SL4A
12
Friday, June 10, 2011
13. Scripting Layer for
Android (SL4A)
Search keyword: android-scripting
13
Friday, June 10, 2011
14. Scripting Layer for
Android (SL4A)
• Started in 2009 by Damon Kohler
• 20% time project at Google.
• Supports Python, Ruby, Perl, Lua, JavaScript,
BeanShell and more.
14
Friday, June 10, 2011
15. Users of SL4A
• Rockets
• SmallSat
15 http://www.flickr.com/photos/jurvetson/
Friday, June 10, 2011
16. Users of SL4A
Cellbots - http://www.cellbots.com
16 http://www.flickr.com/photos/motorbikematt/
Friday, June 10, 2011
25. example.py
Example
import android
droid = android.Android()
droid.webViewShow("/sdcard/sl4a/scripts/html/example.html")
result = droid.eventWaitFor("EVENT_A").result[“data”]
self.droid.log("Received data from EVENT_A: " + result)
example.html
...
<script language= "javascript" type= "text/javascript">
var droid = new Android();
var date = new Date();
droid.eventPost("EVENT_A", "Page Loaded On " + date);
</script>
...
25
Friday, June 10, 2011
26. Before we move on...
• What was discussed so far
• Using the android.py module in Python
programs.
• android.py talks to SL4A, which exposes Android
functionality to clients.
• UI can be built using HTML+Javascript, and it
can talk to Python backend using SL4A events.
26
Friday, June 10, 2011
28. Control robots!
28 http://www.flickr.com/photos/motorbikematt/
Friday, June 10, 2011
29. The Design
direction
control Arduino
Bluetooth
FWD
module Cellbots
LEFT STOP RIGHT firmware
BACK
analog
motor
control
29
Friday, June 10, 2011
30. The Design
Arduino
Bluetooth
module
Arduino
Cellbots
• Cellbots project for firmware
firmware • PDE files on Cellbots site
Android
•
FWD
LEFT STOP RIGHT HTML + Javascript for frontend UI
•
BACK
Python for backend, Cellbot control
• Bluetooth module required (Py4A project)
30
Friday, June 10, 2011
31. Cellbot Controller
• Looks for Cellbot devices via Bluetooth.
• Connects to a selected device and controls
its movement.
• Invokes WebView to display UI.
• Interacts with UI using SL4A events.
Code available at https://github.com/georgegoh/cellbot-controller
31
Friday, June 10, 2011
32. Connecting to the Device
cellbot.py
1. Display scan view
Start scan.html
2. even t(scanBluetooth) User clicks “Scan”
Scan for list of
nearby devices 3. event(bluetoothDevicesFound)
and post
UI shows devices list
luetoothDevice)
Connect to selected 4. event(connectB User selects device
device
32
Friday, June 10, 2011
33. Bluetooth scanning
def scan_bluetooth(self, arg):
""" Discover nearby Bluetooth devices and trigger an SL4A
event "bluetoothDevicesFound" with the list of devices
found.
"""
self.droid.log("Scanning bluetooth devices")
self.discovered_devices =
bluetooth.discover_devices(lookup_names=True)
self.droid.log("Devices found: " +
str(self.discovered_devices))
self.droid.eventPost("bluetoothDevicesFound",
json.dumps(self.discovered_devices))
Code available at https://github.com/georgegoh/cellbot-controller
33
Friday, June 10, 2011
34. Bluetooth connection
def connect_bluetooth_device(self, bd_addr):
""" Connect to a Bluetooth device specified by the bd_addr
address and display the control view for the device.
"""
service = bluetooth.find_service(uuid=CELLBOT_UUID,
address=bd_addr)[0]
self.socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
self.socket.connect((service["host"], service["port"]))
self.droid.webViewShow(CONTROL_VIEW)
Code available at https://github.com/georgegoh/cellbot-controller
34
Friday, June 10, 2011
35. Controlling the Device
cellbot.py
1. Display control view
Start control.html
2. event(move) User clicks a
direction
Send direction
to connected
cellbot
35
Friday, June 10, 2011
36. Motion Control
def move(self, direction):
""" Move a connected Cellbot in one of the following directions:
f - Forward
b - Back
l - Left
r - Right
s - Stop
"""
if self.socket:
self.socket.send(direction + "n")
Code available at https://github.com/georgegoh/cellbot-controller
36
Friday, June 10, 2011
39. Python for
Android (Py4A)
• Additional python modules added:
- Bluez, Twisted, Zope, pyEphem
• Current maintainers:
- Naranjo Manuel Francisco
- Robbie Matthews
39
Friday, June 10, 2011
40. References
• Scripting Layer for Android
http://code.google.com/p/android-scripting
• Python for Android
http://code.google.com/p/python-for-android
• In Love with a Droid
http://android-scripting.blogspot.com/
• Cellbots
http://www.cellbots.com
40
Friday, June 10, 2011
41. Acknowledgements
• Damon Kohler
• Robbie Matthews
• Colleagues @ HP Labs Singapore
41
Friday, June 10, 2011
46. Event loop
while action != "EXIT":
self.droid.log("Python: Waiting for event.")
event_data = self.droid.eventWaitFor("PYTHON").result["data"]
self.droid.log("Python: Event received. Processing...")
# unpack the event data and perform action(if available).
properties = json.loads(event_data)
self.droid.log("Result: " + str(properties))
action = properties["action"]
if action in self.handlers:
self.handlers[action](properties["data"])
Code available at https://github.com/georgegoh/cellbot-controller
46
Friday, June 10, 2011
47. Packaging your app
• Download the template project archive
• http://android-scripting.googlecode.com/hg/android/
script_for_android_template.zip
• Modify the following according to your project
• Import into Eclipse
• Refactor package name from com.dummy.fooforandroid to
your package name.
• Modify or put your script into the res/raw directory.
• http://code.google.com/p/android-scripting/wiki/SharingScripts
47
Friday, June 10, 2011
48. How SL4A works
• Android functionality is abstracted into
methods.
• These methods are grouped in subsystems
called ‘Facades’.
• A JSON-RPC server exposes the methods
contained in these Facades.
48
Friday, June 10, 2011
49. SL4A Architecture
Facade 0
.
Client functionality exposed
via RPC methods
FacadeManager .
.
JsonRpcServer
Facade N
49
Friday, June 10, 2011
50. Facades
• A facade represents a
collection of functionality RPCReceiver
• @Rpc annotation <<implements>>
exposes methods XYZFacade
• @RpcParameter, <<Rpc>> + doIt()
@RpcDefault,
@RpcOptional describe
method arguments.
50
Friday, June 10, 2011
51. Facades
public void dialogCreateInput(final String title, final String message, final String text)
throws InterruptedException {
dialogDismiss();
mDialogTask = new AlertDialogTask(title, message);
((AlertDialogTask) mDialogTask).setTextInput(text);
}
Common/src/com/googlecode/android_scripting/facade/ui/UIFacade.java
public class UiFacade extends RpcReceiver {
RpcReceiver is the abstract
[...] parent of all Facade classes
@Rpc(description = "Create a text input dialog.") @Rpc annotation to indicate
public void dialogCreateInput( method is exposed via RPC
@RpcParameter(name = "title", description = "title of the input box") @RpcDefault("Value") final String title,
@RpcParameter(name = "message", description = "message to display above the input box") @RpcDefault("Please
enter value:") final String message,
@RpcParameter(name = "defaultText", description = "text to insert into the input box") @RpcOptional final
String text)
throws InterruptedException { used in
@RpcParameter
dialogDismiss(); generating user-readable Default values can be
descriptions
mDialogTask = new AlertDialogTask(title, message); specified using the
((AlertDialogTask) mDialogTask).setTextInput(text); @RpcDefault annotation
}
[...]
}
51
Friday, June 10, 2011
52. Code details
For details, see:
• AndroidProxy
• FacadeManagerFactory
• FacadeManager
• FacadeConfiguration
52
Friday, June 10, 2011
53. Facades
http://code.google.com/p/android-scripting/wiki/ApiReference
53
Friday, June 10, 2011
54. Remote Control
• Write programs using your computer keyboard and
monitor and control an Android device remotely.
• Start a SL4A server on your Android, export some
environment variables and import the “android.py”
module.
• http://bit.ly/startpy4a
54 http://xkcd.com/722/
Friday, June 10, 2011
55. SL4A Architecture
Language Interpreter Facade 0
.
functionality exposed
via RPC methods
FacadeManager .
Language .
specific
library JsonRpcServer
Facade N
55
Friday, June 10, 2011
56. What you need
• On your dev machine
• Android SDK
• Python 2.6
• On your Android
• Barcode Scanner
56
Friday, June 10, 2011
57. If you don’t have a
barcode scanner
1. Start the Android Market App.
2. Search for pub: “ZXing Team”
3. Install “Barcode Scanner”
57
Friday, June 10, 2011
58. So I’ve installed
SL4A and Py4A.
What’s next?
58
Friday, June 10, 2011
59. Install more...
• Py4A is not the Python environment.
• It is the manager for the Python
interpreter, extras, and scripts.
• Extras => libraries
• Scripts => sample python scripts to get you
started.
59
Friday, June 10, 2011
60. Install the env
• Start “Python for
Android”
• Click “Install”
60
Friday, June 10, 2011