Python on Your (S60) Phoneby John Littler
Just before Christmas 2004, Nokia put up a version of Python to run on Symbian Series 60 phones. While this is cool just because, is it also useful? Nokia describes its purpose as one of prototyping, teaching, and application development. The prospective audience is application developers who want to use the "native features and resources of the Series 60 phones."
What Is It?
Python is an object-oriented scripting language that features built-in object types, dynamic typing, library and third-party utilities, automatic memory management, built-in tools, and more. O'Reilly publishes several related titles, including Learning Python.
To download this project, see Nokia's Python for Series 60 pages. You need to join the forum before downloading.
The offerings are split between packages that suit various Series 60 SDKs and those that run on the actual phones. For more information on the SDKs and gotchas, especially as far as Linux is concerned, have a look at my earlier article, Roll Your Own Series 60 Phone Applications.
The package that runs on the phone includes a console and various scripts. If you felt like it, you could write ordinary Python code on your phone and debug and send it elsewhere by Bluetooth or email.
An aside is that with a few of these phones, such as the Nokia 6600, you can get your Pocketop infrared mini-keyboard working by merely downloading a driver. That makes it possible to do actual work on a phone. Mstation.org has a review of the Nokia 6600 with pictures of the setup.
Another alternative is to use the Bluetooth console. This connects your PC directly to the Python environment on the phone so you can test and debug. SDK users on Windows can also use an emulator.
Installation and Running Scripts
Transfer a script to the phone by Bluetooth, infrared, or email, and then run it from the console. Scripts can also be built into Series 60 applications so that they appear on the phone as a normal app, which means you can start them without the console. Unfortunately, the tool to do this is available only on Windows, but making an app involves only the creation of a series of files that store information; non-Windows solutions should be along fairly soon.
In Python, a Hello World program looks like this:
print "Hello Kernighan and Ritchie!"
That's it. There are no imports or other worries. There is no semicolon at the end of the line. Type that into the console and press Enter, and away you go. If, on the other hand, you want to display what you've said in a separate GUI, then write instead:
import appuifw appuifw.app.title = u"Hello K and R" appuifw.note(u"Hello Kernighan and Ritchie!", 'info')
That puts up a screen with "Hello K and R" at the top and the required text in a box down below.
appuifw is the class that
interfaces with the Series 60 GUI environment. As you can see, this is a
remarkably small amount of code for GUI programming, even if it doesn't actually
do very much.
Python for Series 60 comes with a selection of scripts, including a simple file browser, the Bluetooth console mentioned earlier, a sports diary, and a weather info script. One script lets you select one of a few prewritten messages and then send it to a number. Here are some excerpts to give a general feel for the Symbian interface. This code can be found in full in the examples/ directory of the Nokia forum.
import appuifw import e32 old_title = appuifw.app.title appuifw.app.title = u"SMS sending"
It would be nice to access the databases that hold contacts, but for the moment, this is how to set up name and number fields:
class NumbersView: def __init__(self, SMS_multiviewApp): self.SMS_multiviewApp = SMS_multiviewApp self.dict = [(u"Jim", "55512345"), (u"Jane", "55567890")] self.names = [item for item in self.dict] self.numbers = [item for item in self.dict] self.numbers_list = appuifw.Listbox(self.names, self.handle_select) self.index = None appuifw.app.body = self.numbers_list
Here's code defining messages to choose from and some setup stuff:
class ChoiceView: def __init__(self, SMS_multiviewApp): self.SMS_multiviewApp = SMS_multiviewApp self.texts = [u"I am late", u"What is for dinner?", u"Do you need anything from the supermarket?", u"How about a round of golf after work?"] self.listbox = appuifw.Listbox(self.texts, self.handle_select) def activate(self): appuifw.app.body = self.listbox appuifw.app.menu = [(u"Select", self.handle_select), (u"Send", self.handle_send)] def handle_select(self): i = self.listbox.current() appuifw.note(u"Selected: " + self.get_text(),'info') def handle_send(self): appuifw.app.activate_tab(3) self.SMS_multiviewApp.handle_tab(3) def get_text(self): return self.texts[self.listbox.current()] class SendView: def __init__(self, SMS_multiviewApp): self.SMS_multiviewApp = SMS_multiviewApp self.log_text = appuifw.Text() self.log_contents = u"" def activate(self): self.log_text.set(self.log_contents) appuifw.app.body = self.log_text appuifw.app.menu =  nbr = self.SMS_multiviewApp.get_number() txt = self.SMS_multiviewApp.get_text() nam = self.SMS_multiviewApp.get_name() if appuifw.query(u"Send message to " + nam + "?", 'query'): t = u"Sent " + txt + " to " + nbr + " (" + nam + ")\n" self.log_contents += t self.log_text.add(t) # messaging.sms_send(nbr, txt) class SMS_multiviewApp: def __init__(self): self.lock = e32.Ao_lock() appuifw.app.exit_key_handler = self.exit_key_handler self.n_view = NumbersView(self) self.c_view = ChoiceView(self) self.t_view = TextView(self) self.s_view = SendView(self) self.views = [self.n_view, self.c_view, self.t_view, self.s_view] appuifw.app.set_tabs([u"Numbers", u"Choice", u"Text", u"Send"], self.handle_tab)
Here's a section from the Bluetooth console script dealing with sockets:
sock=socket.socket(socket.AF_BT,socket.SOCK_STREAM) # For quicker startup, enter here the address and port to connect to. target='' #('00:20:e0:76:c3:52',1) if not target: address,services=socket.bt_discover() print "Discovered: %s, %s"%(address,services) if len(services)>1: import appuifw choices=services.keys() choices.sort() choice=appuifw.popup_menu( [unicode(services[x])+": "+x for x in choices],u'Choose port:') target=(address,services[choices[choice]]) else: target=(address,services.values()) print "Connecting to "+str(target) sock.connect(target) socketio=socket_stdio(sock) realio=(sys.stdout,sys.stdin,sys.stderr) (sys.stdout,sys.stdin,sys.stderr)=(socketio,socketio,socketio)
When I've chatted to people about using Python on Series 60, the first idea that comes up involves reorganizing or adding to data that's already in the phone's database. Right now that's not officially possible, but there are people hacking around their phones doing some reverse engineering, and it looks like they're making quite good progress. Interestingly, some folks in the Java sandpit have just published ways to access the various databases, so it could be that Python will soon follow suit.
One good place for information that doesn't necessarily appear on forum.nokia.com is the PythonForSeries60 Wiki. Quite a few interesting projects are mentioned there.
Hopefully, the above examples show that Python is a relatively clean and straightforward language to play with. The Symbian interface does take a little learning, but if you're feeling lazy, you could just use it on your phone to develop straight Python scripts.
Return to the Python DevCenter.