Pycon2011 android programming-using_python

15,957 views

Published on

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.

Published in: Technology, Education
4 Comments
26 Likes
Statistics
Notes
No Downloads
Views
Total views
15,957
On SlideShare
0
From Embeds
0
Number of Embeds
889
Actions
Shares
0
Downloads
565
Comments
4
Likes
26
Embeds 0
No embeds

No notes for slide

Pycon2011 android programming-using_python

  1. 1. Android Development using Python + George Goh 10 June 2011 PyCon APAC 1Friday, June 10, 2011
  2. 2. HP Labs Singapore http://www.hpl.hp.com/singapore/ 2Friday, June 10, 2011
  3. 3. Agenda • Android Programming (Java vs. Python) • Python Examples / UI Examples • A More Complex Example 3Friday, June 10, 2011
  4. 4. Android Rocks!!! 4Friday, June 10, 2011
  5. 5. Why Python? 5Friday, June 10, 2011
  6. 6. Programming Android 6Friday, June 10, 2011
  7. 7. Plus Python 7 http://www.blangy.com/Photos.htmlFriday, June 10, 2011
  8. 8. A simple program 8Friday, June 10, 2011
  9. 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(); } }); ... 9Friday, June 10, 2011
  10. 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 10Friday, June 10, 2011
  11. 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). 11Friday, June 10, 2011
  12. 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 12Friday, June 10, 2011
  13. 13. Scripting Layer for Android (SL4A) Search keyword: android-scripting 13Friday, June 10, 2011
  14. 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. 14Friday, June 10, 2011
  15. 15. Users of SL4A • Rockets • SmallSat 15 http://www.flickr.com/photos/jurvetson/Friday, June 10, 2011
  16. 16. Users of SL4A Cellbots - http://www.cellbots.com 16 http://www.flickr.com/photos/motorbikematt/Friday, June 10, 2011
  17. 17. SL4A Functionality • ActivityResult • MediaRecorder • Android • Phone • ApplicationManager • Preferences • BatteryManager • SensorManager • Camera • Settings • CommonIntents • Sms • Contacts • SpeechRecognition • Event • ToneGenerator • EyesFree • WakeLock • Location • Wifi • MediaPlayer • UI 17Friday, June 10, 2011
  18. 18. Examples Speech Recognition import android droid = android.Android() message = droid.recognizeSpeech("What is your command?") droid.makeToast("You said: %s" % message.result) 18Friday, June 10, 2011
  19. 19. Examples Text-to-Speech import android droid = android.Android() droid.vibrate() droid.ttsSpeak("Hello, this is android speaking!") 19Friday, June 10, 2011
  20. 20. Examples Web View import android droid = android.Android() message = droid.webViewShow("http://xkcd.com/353/") 20Friday, June 10, 2011
  21. 21. Examples SMS import android droid = android.Android() droid.smsSend(someNumber,"Let’s meet for drinks!") 21Friday, June 10, 2011
  22. 22. Dealing with UI 22Friday, June 10, 2011
  23. 23. UI • WebView Frontend (HTML + Javascript) • Python Backend • Frontend talks to Backend using Events 23Friday, June 10, 2011
  24. 24. Events • eventPost(name, data) • eventWaitFor(eventName, timeout) • eventClearBuffer() • eventPoll(number_of_events) • eventWait() 24Friday, June 10, 2011
  25. 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> ... 25Friday, June 10, 2011
  26. 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. 26Friday, June 10, 2011
  27. 27. A more complete example? 27Friday, June 10, 2011
  28. 28. Control robots! 28 http://www.flickr.com/photos/motorbikematt/Friday, June 10, 2011
  29. 29. The Design direction control Arduino Bluetooth FWD module Cellbots LEFT STOP RIGHT firmware BACK analog motor control 29Friday, June 10, 2011
  30. 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) 30Friday, June 10, 2011
  31. 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 31Friday, June 10, 2011
  32. 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 32Friday, June 10, 2011
  33. 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 33Friday, June 10, 2011
  34. 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 34Friday, June 10, 2011
  35. 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 35Friday, June 10, 2011
  36. 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 36Friday, June 10, 2011
  37. 37. Frontend HTML/JS Control 1 <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> 37Friday, June 10, 2011
  38. 38. Frontend HTML/JS Control 2 <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> 38Friday, June 10, 2011
  39. 39. Python for Android (Py4A) • Additional python modules added: - Bluez, Twisted, Zope, pyEphem • Current maintainers: - Naranjo Manuel Francisco - Robbie Matthews 39Friday, June 10, 2011
  40. 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 40Friday, June 10, 2011
  41. 41. Acknowledgements • Damon Kohler • Robbie Matthews • Colleagues @ HP Labs Singapore 41Friday, June 10, 2011
  42. 42. ? 42Friday, June 10, 2011
  43. 43. Thank you @georgegoh https://github.com/georgegoh/ http://www.linkedin.com/in/georgegoh 43Friday, June 10, 2011
  44. 44. fin 44Friday, June 10, 2011
  45. 45. Bonus/Misc Slides 45Friday, June 10, 2011
  46. 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 46Friday, June 10, 2011
  47. 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 47Friday, June 10, 2011
  48. 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. 48Friday, June 10, 2011
  49. 49. SL4A Architecture Facade 0 . Client functionality exposed via RPC methods FacadeManager . . JsonRpcServer Facade N 49Friday, June 10, 2011
  50. 50. Facades • A facade represents a collection of functionality RPCReceiver • @Rpc annotation <<implements>> exposes methods XYZFacade • @RpcParameter, <<Rpc>> + doIt() @RpcDefault, @RpcOptional describe method arguments. 50Friday, June 10, 2011
  51. 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 } [...] } 51Friday, June 10, 2011
  52. 52. Code details For details, see: • AndroidProxy • FacadeManagerFactory • FacadeManager • FacadeConfiguration 52Friday, June 10, 2011
  53. 53. Facades http://code.google.com/p/android-scripting/wiki/ApiReference 53Friday, June 10, 2011
  54. 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. 55. SL4A Architecture Language Interpreter Facade 0 . functionality exposed via RPC methods FacadeManager . Language . specific library JsonRpcServer Facade N 55Friday, June 10, 2011
  56. 56. What you need • On your dev machine • Android SDK • Python 2.6 • On your Android • Barcode Scanner 56Friday, June 10, 2011
  57. 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” 57Friday, June 10, 2011
  58. 58. So I’ve installed SL4A and Py4A. What’s next? 58Friday, June 10, 2011
  59. 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. 59Friday, June 10, 2011
  60. 60. Install the env • Start “Python for Android” • Click “Install” 60Friday, June 10, 2011

×