Wiley.Mobile.Python.Rapid.prototyping.of.applications.on.the.mobile.platform.Dec.2007 (779889), страница 28
Текст из файла (страница 28)
Otherwisethe user can execute as many commands as she wishes.Naturally, we need some AppleScripts to be executed. Without goinginto details, we give here a simple AppleScript example that first activatesthe Finder application on the Mac and then opens a new file in the148BLUETOOTH AND TELEPHONE FUNCTIONALITYTextEdit application. Make sure you have no other TextEdit file openwhen you run it. Write the following code to a file called edit.scriptand save it to the same folder as the above server program.tell application "Finder"activateopen application file "TextEdit.app" of folder\"Applications" of startup diskend tellThe server is executed similarly to the previous server example.
Now,however, the only sensible message to send from the phone is ‘edit’,which corresponds to the AppleScript file name without the ending‘.script’. Once the message is received by the PC, you should see theTextEdit application start up.Based on this teaser, you can start developing AppleScripts of your ownthat may control various applications, such as iTunes, iPhoto, QuickTime,DVD Player, Keynote, iSync or iCal.
Just save the new AppleScript to somefile that ends with ‘.script’ and add its name to the ALLOWED SCRIPTSlist. For instance, by combining keyboard events from Chapter 5 to thisexample, you could control, say a DVD player, using the arrow keys onyour phone.7.5 Communication with GPS and Other DevicesBesides mobile phones and PCs, there are many devices that can communicate over Bluetooth.
Many of them support RFCOMM, so you candirectly apply the code in this chapter to a large number of use cases.7.5.1 Connecting to GPS over BluetoothIn this section, we connect to an external Bluetooth GPS reader to acquireGPS data (see Figure 7.4).Some modern mobile phones, such as Nokia N95, come with anintegrated GPS receiver.
You can use PyS60 to obtain information fromthe internal GPS, as described in Section 6.4. Unfortunately, accessing theinternal GPS requires some capabilities that are not available for theself-signed PyS60 interpreter (see Appendix A for more information).In contrast, you can use an external GPS receiver without any specialcapabilities just by connecting to it over Bluetooth.Data that comes from the external GPS receiver follows a standardspecified by the National Marine Electronics Association (NMEA).
Youcan find a description of this format in many sources on the web, forinstance, at www.gpsinformation.org/dale/nmea.htm.COMMUNICATION WITH GPS AND OTHER DEVICES149BluetoothFigure 7.4 Bluetooth from phone to GPSThe format is line-oriented: the GPS sends one message per line. Theline contains typically many fields, which are separated by commas. Theline begins with the dollar sign, $, which is followed by a word thatspecifies the data type.
The messages look like this:$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47This line has the data type GPGGA and it contains 15 fields. Mostimportantly, the third to sixth fields contain the latitude and longitudeof the current position. On the above line, the latitude is 48.07.038’Nand the longitude is 11.31.000’E. You can find this information and themeaning of other fields, in the NMEA specification. These coordinatescan be readily plotted to many modern applications, such as GoogleMaps.Besides the GPGGA lines, the data stream from the GPS receivercontains many other types of lines as well, as specified by NMEA.However, simple GPS-tracking software, such as the one presented below,might need only the GPGGA lines that specify the current position.Example 62: GPS readerimport socketaddress, services = socket.bt_discover()print "Discovered: %s, %s" % (address, services)target = (address, services.values()[0])conn = socket.socket(socket.AF_BT, socket.SOCK_STREAM)conn.connect(target)to_gps = conn.makefile("r", 0)while True:msg = to_gps.readline()150BLUETOOTH AND TELEPHONE FUNCTIONALITYif msg.startswith("$GPGGA"):gps_data = msg.split(",")lat = gps_data[2]lon = gps_data[4]breakto_gps.close()conn.close()print "You are now at latitude %s and longitude %s" % (lat, lon)This example is based on techniques that are already familiar to youfrom the previous examples.
First, you choose the GPS receiver fromthe list of discovered devices. It is not necessary to choose a service,as the GPS receiver provides only one. The socket is connected tothe receiver in the usual way. If you know the address of your GPSreceiver beforehand, or you have saved it to a file, you can skip thetime-consuming socket.bt discover() function and connect to thespecified address directly.We receive and skip lines from the GPS until we get the one thatcontains the current coordinates, that is, the one that begins with thestring "$GPGGA".
After this, we exit from the loop and print out thecoordinates.You could extend the example, for instance, by saving the coordinatesin a file so that you can plot them to Google Earth, or, you could receivethe map of this location straight away with the MopyMaps! application,which is described in Section 9.2.7.5.2 Connecting to Other Devices over BluetoothIn Chapter 11, we present more real-world uses of Bluetooth.
We showhow to use Bluetooth to communicate with a sensor board kit, Arduino(see Figure 7.5), which is an extremely simple, yet powerful platform forbuilding custom hardware. We also describe how PyS60 and Bluetoothwere used to build an autonomous robotic vacuum cleaner and how tocontrol sound-generation software called Max/MSP.BluetoothFigure 7.5Bluetooth from a phone to a sensor boardTELEPHONE FUNCTIONALITY AND CONTACTS151As you will notice, these examples are similar to the previous examplesthat use RFCOMM. After reading these sections you have already seeneverything needed to build practical, as well as artistic and esoteric,applications using Bluetooth!7.6 Telephone Functionality and ContactsThe telephone module provides an API to the telephone functionalityof the mobile phone, so it is possible to use a mobile phone as a phone!Compared to many other modules in this book, the telephone moduleis particularly simple.The module includes only two functions: telephone.dial() andtelephone.hang up().
The dial() function accepts a telephonenumber as a string, as it may contain special characters, such as the plussign. Note that if there is an call in process when the dial() function iscalled, the previous call is put on hold and a new call is established.Example 63: Telephoneimport telephone, e32telephone.dial('+1412345602')e32.ao_sleep(10)telephone.hang_up()If you start recording sound when a call is active, the phone call isrecorded.
See Example 26 for a simple sound recorder that can easily becombined with the telephone module. Ethical implications are left asan exercise for the reader.The contacts module offers an API to the phone’s address book.Although in the simplest form the address book could be a dictionary,which has names as keys and phone numbers as values, the modernmobile phone provides a sophisticated database which can handle richforms of contact information. Correspondingly, the contacts moduleincludes an extensive set of functions and objects that hook into theunderlying contacts service that is provided by the operating system.The PyS60 API documentation contains a detailed description of themodule, so we do not repeat it here.
Instead, we give an overview of themost typical use case: finding the phone number of an individual, givena name as a string. The following steps are needed:1. Open the contacts database with db = contacts.open().2. Find an entry in the database which contains the desired name usingdb.find(name). The matching entries, if any, are returned in a list.Each item of the list is a Contact object. Let’s denote one such itemwith match.152BLUETOOTH AND TELEPHONE FUNCTIONALITY3.The person’s name can be found with match.title. In addition,a Contact object may have over 20 fields, such as name, job title,state and email address. If you need to call the person, typically themobile number field might contain the needed information.
It canbe retrieved with field = match.find("mobile number").This returns a list of fields, as the person may have multiple mobilephones. It is also possible that the requested field might not exist, inwhich case None is returned.4.The field variable is an object of type ContactField. Mostimportantly, the actual value of the field can be found in field.value. This is, finally, the phone number string.The following example is a straightforward application of the stepsoutlined above.
It lets you search for a string, name, in the contactsdatabase. It shows a selection list that contains the matching items andretrieves the mobile phone number for the chosen entry. Finally, it callsthis number using telephone.dial().Example 64: Contactsimport contacts, appuifw, telephonename = appuifw.query(u'Call to', 'text')db = contacts.open()entries = db.find(name)names = []for item in entries:names.append(item.title)if names:index = appuifw.selection_list(names, search_field=0)num = entries[index].find('mobile_number')if num:telephone.dial(num[0].value)else:appuifw.note(u'Missing mobile phone number', 'error')else:appuifw.note(u'No matches','error')Similar functionality was used in the Hangman SMS server in Section4.5.7.7 System InformationThe sysinfo module offers an API for checking the system informationof the mobile device. The following functions are provided:• battery() returns the current battery level ranging from 0 to 7.