Upload
george-goh
View
13.911
Download
6
Embed Size (px)
DESCRIPTION
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.
Citation preview
Android Development using Python
George Goh10 June 2011PyCon APAC
1
+Friday, June 10, 2011
HP Labs Singapore
2
http://www.hpl.hp.com/singapore/
Friday, June 10, 2011
Agenda
• Android Programming (Java vs. Python)
• Python Examples / UI Examples
• A More Complex Example
3
Friday, June 10, 2011
Android Rocks!!!
4
Friday, June 10, 2011
Why Python?
5
Friday, June 10, 2011
Programming Android
6
Friday, June 10, 2011
Plus Python
7 http://www.blangy.com/Photos.htmlFriday, June 10, 2011
A simple program
8
Friday, June 10, 2011
Simple Program in Javapackage 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
Simple Program in Python
10
• Java program: 35 SLOC
• Equivalent Python program: 4 SLOC
import android
droid = android.Android()name = droid.getInput("Hello!", "What is your name?")droid.makeToast("Hello, %s" % name.result)
Friday, June 10, 2011
Android module
• Exposes android functionality via an Android() object.
• Talks to a service called SL4A (Scripting Layer for Android).
11
import android
droid = android.Android()name = droid.getInput("Hello!", "What is your name?")droid.makeToast("Hello, %s" % name.result)
Friday, June 10, 2011
AndroidPython Interpreter
android.py
Invoking functionality
SL4A
functionality exposedvia RPC methods
12
import android
droid = android.Android()name = droid.getInput("Hello!", "What is your name?")droid.makeToast("Hello, %s" % name.result)
Friday, June 10, 2011
Scripting Layer for Android (SL4A)
Search keyword: android-scripting13
Friday, June 10, 2011
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
Users of SL4A
• Rockets
• SmallSat
15 http://www.flickr.com/photos/jurvetson/
Friday, June 10, 2011
Users of SL4ACellbots - http://www.cellbots.com
16 http://www.flickr.com/photos/motorbikematt/
Friday, June 10, 2011
SL4A Functionality
17
• ActivityResult
• Android
• ApplicationManager
• BatteryManager
• Camera
• CommonIntents
• Contacts
• Event
• EyesFree
• Location
• MediaPlayer
• MediaRecorder
• Phone
• Preferences
• SensorManager
• Settings
• Sms
• SpeechRecognition
• ToneGenerator
• WakeLock
• Wifi
• UI
Friday, June 10, 2011
Examples
18
import android
droid = android.Android()message = droid.recognizeSpeech("What is your command?")droid.makeToast("You said: %s" % message.result)
Speech Recognition
Friday, June 10, 2011
Examples
19
Text-to-Speech
import android
droid = android.Android()droid.vibrate()droid.ttsSpeak("Hello, this is android speaking!")
Friday, June 10, 2011
Examples
20
Web View
import android
droid = android.Android()message = droid.webViewShow("http://xkcd.com/353/")
Friday, June 10, 2011
Examples
21
SMS
import android
droid = android.Android()droid.smsSend(someNumber,"Let’s meet for drinks!")
Friday, June 10, 2011
Dealing with UI
22
Friday, June 10, 2011
UI
• WebView Frontend (HTML + Javascript)
• Python Backend
• Frontend talks to Backend using Events
23
Friday, June 10, 2011
Events
• eventPost(name, data)
• eventWaitFor(eventName, timeout)
• eventClearBuffer()
• eventPoll(number_of_events)
• eventWait()
24
Friday, June 10, 2011
Example
25
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)
...<script language= "javascript" type= "text/javascript"> var droid = new Android(); var date = new Date();
droid.eventPost("EVENT_A", "Page Loaded On " + date);</script>...
example.html
example.py
Friday, June 10, 2011
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
A more complete example?
27
Friday, June 10, 2011
Control robots!
28 http://www.flickr.com/photos/motorbikematt/
Friday, June 10, 2011
The Design
29
ArduinoCellbotsfirmware
analogmotorcontrol
Bluetoothmodule
directioncontrol
FWD
LEFT RIGHT
BACK
STOP
Friday, June 10, 2011
The DesignArduino
• Cellbots project for firmware
• PDE files on Cellbots site
Android
• HTML + Javascript for frontend UI
• Python for backend, Cellbot control
• Bluetooth module required (Py4A project)
30
FWD
LEFT RIGHT
BACK
STOP
ArduinoCellbotsfirmware
Bluetoothmodule
Friday, June 10, 2011
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.
31
Code available at https://github.com/georgegoh/cellbot-controller
Friday, June 10, 2011
Connecting to the Device
32
cellbot.py
Start
Scan for list of nearby devices
and post
Connect to selected device
scan.html
User clicks “Scan”
UI shows devices list
User selects device
1. Display scan view
2. event(scanBluetooth)
3. event(bluetoothDevicesFound)
4. event(connectBluetoothDevice)
Friday, June 10, 2011
Bluetooth scanning
33
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
Friday, June 10, 2011
Bluetooth connection
34
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
Friday, June 10, 2011
Controlling the Device
35
cellbot.py
Start
Send directionto connected
cellbot
control.html
User clicks a direction
1. Display control view
2. event(move)
Friday, June 10, 2011
Motion Control
36
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
Friday, June 10, 2011
Frontend HTML/JS Control 1
37
<head> <title>Robot demo</title> <script type="text/javascript" src="./js/mootools.js"></script> <script language="javascript" type="text/javascript"> var droid=new Android();
function postToPython(data) { droid.eventPost("PYTHON", JSON.stringify(data)); }
function move(direction) { postToPython({action: "move", data: direction}); }
window.addEvent("domready", function() { $('bFwd').addEvent('click', function() { move("f"); }); $('bLeft').addEvent('click', function() { move("l"); }); $('bStop').addEvent('click', function() { move("s"); }); $('bRight').addEvent('click', function() { move("r"); }); $('bBack').addEvent('click', function() { move("b"); }); $('bExit').addEvent('click', function() { postToPython({action:"EXIT", data:""}); }); }); </script></head>
Friday, June 10, 2011
Frontend HTML/JS Control 2
38
<body> <table align=center> <tr> <td /> <td align=center><button id="bFwd">FWD</button></td> <td /> </tr> <tr> <td align=center><button id="bLeft">LEFT</button></td> <td align=center><button id="bStop">STOP</button></td> <td align=center><button id="bRight">RIGHT</button></td> </tr> <tr> <td /> <td align=center><button id="bBack">BACK</button></td> <td /> </tr> </table> <button id="bExit">EXIT</button></body>
Friday, June 10, 2011
Python for Android (Py4A)
• Additional python modules added:- Bluez, Twisted, Zope, pyEphem
• Current maintainers:- Naranjo Manuel Francisco- Robbie Matthews
39
Friday, June 10, 2011
References
• Scripting Layer for Androidhttp://code.google.com/p/android-scripting
• Python for Androidhttp://code.google.com/p/python-for-android
• In Love with a Droidhttp://android-scripting.blogspot.com/
• Cellbotshttp://www.cellbots.com
40
Friday, June 10, 2011
Acknowledgements
• Damon Kohler
• Robbie Matthews
• Colleagues @ HP Labs Singapore
41
Friday, June 10, 2011
?
42
Friday, June 10, 2011
@georgegoh
https://github.com/georgegoh/
http://www.linkedin.com/in/georgegoh
43
Thank you
Friday, June 10, 2011
fin
44
Friday, June 10, 2011
Bonus/Misc Slides
45
Friday, June 10, 2011
Event loop
46
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
Friday, June 10, 2011
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
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
SL4A Architecture
Facade 0
JsonRpcServerFacade N
.
.
.FacadeManagerfunctionality exposed
via RPC methodsClient
49
Friday, June 10, 2011
Facades
• A facade represents a collection of functionality
• @Rpc annotation exposes methods
• @RpcParameter, @RpcDefault, @RpcOptional describe method arguments.
50
RPCReceiver
XYZFacade
<<Rpc>> + doIt()
<<implements>>
Friday, June 10, 2011
Facades
Common/src/com/googlecode/android_scripting/facade/ui/UIFacade.javapublic class UiFacade extends RpcReceiver {
[...]
@Rpc(description = "Create a text input dialog.") public void dialogCreateInput( @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 { dialogDismiss(); mDialogTask = new AlertDialogTask(title, message); ((AlertDialogTask) mDialogTask).setTextInput(text); }
[...]}
51
public void dialogCreateInput(final String title, final String message, final String text) throws InterruptedException { dialogDismiss(); mDialogTask = new AlertDialogTask(title, message); ((AlertDialogTask) mDialogTask).setTextInput(text);}
@Rpc annotation to indicate method is exposed via RPC
@RpcParameter used in generating user-readable
descriptionsDefault values can be
specified using the @RpcDefault annotation
RpcReceiver is the abstract parent of all Facade classes
Friday, June 10, 2011
Code details
For details, see:
• AndroidProxy
• FacadeManagerFactory
• FacadeManager
• FacadeConfiguration
52
Friday, June 10, 2011
Facades
http://code.google.com/p/android-scripting/wiki/ApiReference
53
Friday, June 10, 2011
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
Language specific library
SL4A Architecture
Facade 0
JsonRpcServerFacade N
.
.
.FacadeManagerfunctionality exposed
via RPC methods
Language Interpreter
55
Friday, June 10, 2011
What you need• On your dev machine
• Android SDK
• Python 2.6
• On your Android
• Barcode Scanner
56
Friday, June 10, 2011
If you don’t have a barcode scanner1. Start the Android Market App.
2. Search for pub: “ZXing Team”
3. Install “Barcode Scanner”
57
Friday, June 10, 2011
So I’ve installedSL4A and Py4A.
What’s next?
58
Friday, June 10, 2011
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
Install the env
60
• Start “Python for Android”
• Click “Install”
Friday, June 10, 2011