Symbian developer community

 
wiki

Platform Services (Python on Symbian)

From Symbian Developer Community

Jump to: navigation, search

Original Authors: Pankaj Nathani and Bogdan Galiceanu

Contents

Introduction

In the earlier chapters we have seen the use of various modules like calendar, messaging, logs, location, positioning, sensor and many more, which are helpful to utilize the various features of the smartphone. However, there are instances when the use of these modules is not effective enough to achieve the required features in an application. For e.g. the logs module is only able to read the log entries but not to create a log or delete a log entry.

To overcome such situations, there exists a module called scriptext, which gives the PyS60 developer access to plethora of platform services using generic APIs. The scriptext module gives an effective access to most of the service APIs of the device like Application Manager, Calendar, Contacts, Landmarks, Location, Logging, Messaging, Media Management, Sensors and Sys Info. Having said that, in this chapter we would understand how to use these platform services in our applications for performing various tasks.

Note: The Platform services (scriptext) and other individual modules are collectively responsible for providing access to various features of the devices. One of them cannot be considered complete without the other. For example, the scriptext module does not support Bluetooth API and the developer should use the btsocket module for performing Bluetooth operations.


Figure 1: PyS60 Platform Services

Platform services can be accessed in PyS60 using the scriptext module. Scriptext uses two simple methods load and call to initiate and using the services respectively.

Load

A Service object can be instantiated using the load method. The syntax of using the load API is as follows,

import scriptext
scriptext_handle = scriptext.load(<provider>, <interface>)

where <provider> is a string specifying the name of the service provider (for e.g. 'Service.AppManager') and <interface> is a string specifying one the names of supported interfaces of the <provider> (for e.g. 'IAppManager')

For example, to load the messaging service, we use the following,

 
import scriptext
messaging_handle = scriptext.load("Service.Messaging", "IMessaging")

(IMessaging is a supported interface of the Messaging service)

Call

The call method is used to request a service or operation (synchronous or asynchronous) from a service provider. The syntax of call method is as follows,

For requesting synchronous services,

result = service_instance_object.call(<operation>, parameters)

where <operation> specifies the requested service and parameters is a dictionary specifying input parameters for the requested service. In the below code, GetList is the <operation> and {'Type': u'Inbox'} represents the parameters.

sms_iter = messaging_handle.call('GetList', {'Type': u'Inbox'})

GetList is the name of the request and Inbox is the argument for the services. Basically, the above line of code would return all the SMS in the inbox as an iterable map, which can be used for retrieving more details.

For requesting asynchronous services,

 result = service_instance_object.call(<operation>, parameters, callback=callback_function)

In addition to operation and parameter arguments, an asynchronous service also needs a callback function. The callback function can be any user defined function and it would called when there is need to handle the asynchronous request.

For example,

import scriptext
 
def media_callback(trans_id, event_id, output_params):
print trans_id
print event_id
print output_params
 
 
media_handle = scriptext.call('Service.MediaManagement', 'IDataSource')
 
media_trans_id = media_handle.call('GetList', {'Type': u'FileInfo', u'FileExtension', 'StartRange': u'.mp3'},'Sort': {'Key': u'FileName', 'Order': u'Ascending'}}, callback=media_callback)

The above code requests and prints for list of mp3 files in an ascending order. The callback function media_callback is called for every mp3 file that is present.

The callback function is called after an asynchronous service request has 3 arguments viz. transactionID, eventID and outParam.

  • transactionID - It is the unique transaction ID associated with the particular asynchronous request. It is returned as part of the result of the initial asynchronous call.
  • eventID - Specifies the asynchronous operation status. The probably values of an event id can EventCompleted, EventCanceled, EventError, EventStopped, etc. A complete list of event ids is available here with a brief description of what they indicate.
  • outParam - It is holds the output of the asynchronous call in a dictionary.
    • outParam['ReturnValue']}} - Contains information requested by the asynchronous call that initiated the callback. Not all asynchronous calls return this property. The existence of 'ReturnValue' depends on the Platform Service API and the method that was called. If 'ReturnValue' is not present, the outParam would only contain 'ErrorCode' and 'ErrorMessage'.
    • outParam['ErrorCode'] - Specifies an error code. A complete list of pre-defined error codes is available here.
    • outParam['ErrorMessage'] - Describes the error message.

To cancel an outstanding asynchronous request Cancel is passed as an argument to the call function as illustrated below.

serviceInstance.call('Cancel', {'TransactionID': serviceTransactionID})

For e.g. the below line cancels the asynchronous request shown in the above code snippet.

media_handle.call('Cancel', {'TransactionID': media_trans_id })

Application Manager

If you have been using an S60 phone, you might be familiar with the application manager. Application manager is an application implementing the most standard use of installing and uninstalling applications on the phone. Using platform services in Python i.e. scriptext module, it is possible to retrieve information about the applications and user installed packages from the phone. Also, it is possible to request for a particular operation by passing the input parameters.

As, illustrated in the figure below, the Application manager provides 3 basic services for these purposes viz. GetList, LaunchApp and LaunchDoc.


Figure 2: Application Manager Services

The Application Manager API has to be loaded before using any of the services it provides. It can be loaded by the following code,

 
import scriptext
appmanager_handle = scriptext.load('Service.AppManager', 'IAppManager')


GetList

GetList can be used in Synchronous mode to retrieve information about the all applications. user installed packages and handler applications. Let us take an example to see how GetList works.

import scriptext
#initialize empty list for application info
application_info= []
#Load the Application Manager API
appmanager_handle = scriptext.load('Service.AppManager', 'IAppManager')
# Call the GetList function
appmanager_info = appmanager_handle.call('GetList', {'Type': u'Application'})
# Populate the empty list with information of installed applications
for item in appmanager_info:
application_info= .append(item['UID'])
application_info= .append(item['Path'])
application_info= .append(item['Caption'])
application_info= .append(item['ShortCaption'])
print application_info


LaunchApp

LaunchApp can be used both synchronously and asynchronously to launch an application. It takes the UID of the application as an argument.

Using LaunchApp synchronously,

 
appmanager_id = appmanager_handle.call('LaunchApp', {'ApplicationID': u's60uid:// 0xE674C90B'})

The above line of code would launch the application with UID 0xE674C90B.

Using LaunchApp asynchronously,

appmanager_id = appmanager_handle.call('LaunchApp', {'ApplicationID': u's60uid:// 0xE674C90B'},  callback= callback_function)

The above line of code would launch the application with UID 0xE674C90B and the execution of code would return to the callback_function, which is defined as the callback function.

LaunchDoc

Alike LaunchApp, LaunchDoc can also be used either synchronously or asynchronously to launch a document in embedded mode. It takes the document path, MimeType (optional) and options (optional) as an argument.

Using LaunchDoc synchronously,

appmanager_id = appmanager_handle.call('LaunchDoc', {'Document': {'DocumentPath': u'C:\\data\\Image.jpg'}})

The above line of code would launch the Image.jpg.

Using LaunchDoc asynchronously,

appmanager_id = appmanager_handle.call('LaunchDoc', {'Document': {'DocumentPath': u'C:\\data\\Image.jpg'}}, callback= callback_function)

The above line of code would launch the Image.jpg and return the execution of code to callback_function.

Calendar

The calendar service API enables Python developers to access, create, and manage calendars and their entries stored on a device. As shown in the figure below, calendar services API provides 6 services viz. GetList, Add, Delete, Import, Export and RequestNotification.


Figure 3: Calender Services

The Calendar API has to be loaded before using any of the services it provides. Use Service.Calendar to identify the service provider and IDataSource to identify the supported interface, as illustrated in the following code.

 
import scriptext
calendar_handle = scriptext.load('Service.Calendar', 'IDataSource')


GetList

GetList service can be used synchronously to retrieve a list of available calendars or a list of calendar entries. The information to be retrieved can filtered by the arguments passed when using the service. Entries in the calendar can be of type Meeting, ToDo, Anniversary, DayEvent and Reminder.

For e.g. the following code can be used to list all the ToDo entries in the calendar.

ToDo_list = calendar_handle.call('GetList', {'Type': u'CalendarEntry', 'Filter': {'CalendarName': u'C:Calendar', 'Type': u'ToDo'}})

Once a list of events is retrieved using GetList, various attributes of the event can be retrieved.

For e.g. the following code snippet retrieves a list of ToDo events and prints some of its attributes. Please refer to the PyS60 documentation for more information on attributes of event types.

 
import scriptext
 
# Load Calendar service
calendar_handle = scriptext.load('Service.Calendar', 'IDataSource')
ToDo_list = calendar_handle.call('GetList', {'Type': u'CalendarEntry', 'Filter': {'CalendarName': u'C:Calendar', 'Type': u'ToDo'}})
for ToDo in ToDo_list:
print 'Id = ' + ToDo['id']
print 'Summary = ' + ToDo[‘Summary’]
 
value = ToDo['EndTime']
print "ToDo End time is ", value.day, value.month, value.year, value.hour, ":", value.minute, ":", value.second
 
value = meeting['AlarmTime']
print "ToDo Alarm time is ", value.day, value.month, value.year, value.hour, ":", value.minute, ":", value.second
 
print ‘Status =’ + ToDo[‘Status’]
 


Add

We saw how to retrieve calendar entries using GetList, but what happens if we need to add a calendar entry? Add is used synchronously to add a new calendar, calendar entries or to modify an existing calendar entry on the device.

For e.g., the following code adds a To Do entry to the calendar,

alarm_time = datetime.datetime(2009,12,12,13,0,0)
end_time = datetime.datetime(2009,12,12,14,0,0)
 
calendar_handle.call('Add', {'Type': u'CalendarEntry', 'Item': {'Type': u'ToDo', 'Summary': u'This is the ToDo Summary', 'EndTime': end_time, 'AlarmTime': end_time}})

Likewise, other event entries, such as Meeting, Anniversary, DayEvent and Reminder can also be added to the calendar in the similar manner. The attributes specified may vary for different event type entries. Please refer to the PyS60 documentation for more information on attributes of event types.

An existing entry may be modified by specifying the id as an argument.

Delete

Delete can be used synchronously or asynchronously to remove/delete a calendar or a calendar entry from the device. The default calendar of the device cannot be deleted.

Using Delete synchronously,

event_id = calendar_handle.call('Delete', {'Type': u'CalendarEntry', 'id': del_id_list})

Using Delete asynchronously,

event_id = calendar_handle.call('Delete', {'Type': u'CalendarEntry', 'id': del_id_list}, callback= callback_function)

where del_id_list is the list of the entries to be deleted and callback_function is the user defined callback function..

For e.g. the following code asynchronously deletes all ToDo entries from the calendar,

import scriptext
 
# Load Calendar service
calendar_handle = scriptext.load('Service.Calendar', 'IDataSource')
 
# Populate ToDo_list with all the ToDo entries in the calendar
ToDo_list = calendar_handle.call('GetList', {'Type': u'CalendarEntry', 'Filter': {'CalendarName': u'C:Calendar', 'Type': u'ToDo'}})
 
# Callback function will be called when the requested service is complete
def callback_function(trans_id, event_id, input_params):
print “Entry Deleted”
 
# Delete the entries in ToDo_list
event_id = calendar_handle.call('Delete', {'Type': u'CalendarEntry', 'IdList': ToDo_list}, callback= callback_function)
 
print “Waiting for the request to be completed”
lock.wait()
print “Request Complete”


Import

Import service can be used synchronously or asynchronously to import entries into the calendar from a file. Currently, the file formats supported by import service are ICal or VCal.

Using Import synchronously,

calendar_handle.call('Import', {'Type': u'CalendarEntry', 'FileName': u'C:\\data\\Imported.txt', 'Format': u'ICal'})

The above code would import the calendar entries from Imported.txt file. The file format used here is ICal. The same format must be used while exporting the entries to the calendar using the Export service.

Using Import ssynchronously,

calendar_handle.call('Import', {'Type': u'CalendarEntry', 'FileName': u'C:\\data\\ Imported.txt', 'Format': u'VCal'}, callback= callback_function))

The above code will import the calendar entries from Imported.txt to the calendar and return the execution to the callback_function which is the user defined callback function.

Export

Export service can be used synchronously or asynchronously to export entries from the calendar to a file. Alike Import service, ICal and VCal are the supported file formats for Export service too.

Using Import synchronously,

calendar_handle.call('Export', {'Type': u'CalendarEntry', 'FileName': u'C:\\Data\\Exported.txt', 'Format': u'VCal'})

Using the above code would export all the calendar entries to the Exported.txt file using VCal file format.

Using Import asynchronously,

calendar_handle.call('Export', {'Type': u'CalendarEntry', 'FileName': u'C:\\data\\Exported.txt', 'Format': u'VCal'}, callback= callback_function))

Using the above code would export all the calendar entries to the Exported.txt file using VCal file format and return the code execution to callback_function which is the user defined callback function.

RequestNotification

It may sometime happen that one wants to be notified when the calendar entries are added or deleted. For facilitating this functionality in PyS60, the calendar API offers the RequestNotification service. RequestNotification service can be used asynchronously to notify the registered client when events such as entry addition, deletion or updating occur in a given calendar.

For e.g. the following code requests for calendar entry notifications. Whenever a calendar entry is modified, edited or deleted the callback function is called with arguments – trans_id, event_id and input_params.

 
import scriptext
import e32
 
lock = e32.Ao_lock()
calendar_handle = scriptext.load('Service.Calendar', 'IDataSource')
 
def calendar_callback(trans_id, event_id, input_params):
if event_id != scriptext.EventCompleted:
# Check the event status
print "Error in retrieving required info"
print "Error code is: " + str(input_params["ReturnValue"]["ErrorCode"])
if "ErrorMessage" in input_params["ReturnValue"]:
print "Error message is: " + input_params["ReturnValue"]["ErrorMessage"]
else:
print "Modification is: " + str(input_params["ReturnValue"]["ChangeType"])
lock.signal()
 
# Make a request to get notification
event_id = calendar_handle.call("RequestNotification", {'Type': u'CalendarEntry'}, callback=calendar_callback)
 
lock.wait()
 

Contacts

Using the services provided by the contacts API we can access and manage the contacts list on the device. The contact API provides services to retrieve contact or group information, add contact or group, edit a particular contact or group, import and export a contact and delete a contact or group item. These services are illustrated in the below figure.


Figure 4: Contacts Services

The Contacts API has to be loaded before using any of the services it provides. Use Service.Contact to identify the service provider and IDataSource to identify the supported interface, as illustrated in the following code.

import scriptext
contact_handle = scriptext.load('Service.Contact', 'IDataSource')

GetList

The GetList service offered by contacts API is very similar to the one offered by the calendar API. The only difference is GetList for contacts API can be used synchronously as well as asynchronously. GetList service can be used to retrieve list of contacts, contact groups, or contacts databases.

The list of contacts and contact groups can be retrieved from the mentioned contacted database. If no database is mentioned, the default database is considered and used.

Using GetList synchronously,

list_contacts = contacts_handle.call('GetList', {'Type': u'Contact', 'Filter': {'SearchVal': u'Pankaj'}})

The above code populates the list list_contacts with the list of contacts with ‘Pankaj’ in their First Name and Last Name fields.

Using GetList asynchronously,

event_id = contacts_handle.call('GetList', {'Type': u'Contact', 'Filter':{'SearchVal': u'Pankaj'}}, callback=callback_function)

The above code calls the user defined callback function, callback_function, after getting the list of contacts with ‘Pankaj’ in their First Name and Last Name fields.

Note: In S60 3rd Edition and S60 3rd Edition FP1, the SearchVal searches in all the contact fields. However in S60 3rd edition FP2 onwards, SearchVal searches only in First Name and Last Name field.

Add

Add can be used synchronously or asynchronously to add or edit a contact or contact group to a contacts database. If the contact or contact group already exists in the database, it is replaced with the new entry.

For example,

 
contacts_handle.call('Add', {'Type': u'Contact', 'Data':
{'FirstName': {'Label': u'first name', 'Value': u'Burton'},
'LastName': {'Label': u'last name', 'Value': u'Jerome'},
'MobilePhoneGen': {'Label': u'mobile', 'Value': u'9009132813'},
'EmailHome': {'Label': u'email', 'Value': u'Burton@Jerome.com'}}})
 

The above code would add the contact to the contacts database with the following details.

First Name: Burton
Last Name: Jerome
Mobile: 9009132813
Email (Home): Burton@Jerome.com
 

Delete

Delete can be used synchronously or asynchronously to delete one or more contacts or contact groups from a given contact database. If no database is given the default database is considered and used.

For example,

event_id = contacts_handle.call('Delete', {'Type': u'Contact', 'Data': {'IdList': [req_id]}}, callback=callback_function)

The above code deletes the contact with the req_id and calls the callback_function which is the user defined callback function.

Import

Import can be used synchronously or asynchronously to import contacts from a vCard file.

Using Import synchronously,

event_id = contacts_handle.call('Import', {'Type': u'Contact','Data':{'SourceFile':u'c:\\Data\\contacts.txt'}})

Using Import asynchronously,

event_id = contacts_handle.call('Import', {'Type': u'Contact','Data':{'SourceFile':u'c:\\Data\\ contacts.txt'}},callback=callback_function)

Export

Export can be used synchronously or asynchronously to export contacts to a vCard file.

Using Export synchronously,

event_id = contacts_handle.call('Export', {'Type': u'Contact','Data':{'SourceFile':u'c:\\Data\\contacts.txt'}})

Using Export asynchronously,

event_id = contacts_handle.call('Export', {'Type': u'Contact','Data':{'SourceFile':u'c:\\Data\\contacts.txt'}},callback=callback_function)

Organize

Organize can be used synchronously or asynchronously, to add contacts to a contact group or remove contacts from a contact group.

Using Organize asynchronously,

event_id = contacts_handle.call('Organise', {'Type': u'Group','Data': {'id': unicode(req_groupid[0]),'IdList': [req_id]}, 'OperationType': u'Associate'},callback=export_contact)

Landmarks


Figure 5: Landmarks Services

Location

Through the Location service API, scriptext not only gives you access to the physical location of the device but also allow you to track the movements of the device and perform calculations based on location information.

Please refer to Location Based Application chapter for information on how the physical location of the device can be interpreted.



Figure 6: Location Services

The Location API can be loaded by the following code,

import scriptext
location_handle = scriptext.load('Service.Location', 'IDataSource')

GetList

GetList can be used synchronously or asynchronously to retrieve the current location of the device.

Using GetList synchronously,

Location_List = location_handle.call('GetList', {'LocationInformationClass': u'BasicLocationInformation', 'Updateoptions': {'UpdateInterval':u'1', 'UpdateTimeOut': u'15', 'UpdateMaxAge' :u'0', 'PartialUpdates': u'False'}})

Using GetList asynchronously,

event_id = location_handle.call('GetList', {'LocationInformationClass':  u'BasicLocationInformation', 'Updateoptions': {'UpdateInterval': u'1', 'UpdateTimeOut': u'15', 'UpdateMaxAge': u'0', 'PartialUpdates': u'False'}}, callback= callback_function)

callback_function is the user defined callback function.

Trace

Trace can be used to track the movement of the device - It gives updates on the location of the device based on a predefined update interval. Trace can only be used asynchronously.

For example,

event_id = location_handle.call('Trace', {'LocationInformationClass': u'GenericLocationInfo', 'Updateoptions': {'UpdateInterval': u'10', 'UpdateTimeOut': u'50', 'UpdateMaxAge': u'5', 'PartialUpdates': u'True'}})

CancelNotification

CancelNotification can be used synchronously to cancel asynchronous calls – for example – Add and Trace.

For example,

cancel_output = location_handle.call('CancelNotification', {'CancelRequestType': u'GetLocCancel'})

MathOperations

MathOperations is used to perform calculations on retrieved or user provided location information.

The mathematical operations possible with MathOperations include finding distance between two given locations, finding bearing between two given locations and calculating a new location based on movement from a source location.

For example, the following line of code is used to find the distance (in metres) between two provided locations.

distance = location_handle.call('MathOperations', {'MathRequest': u'FindDistance', 'DistanceParamSource': {'Longitude': u'10', 'Latitude': u'15', 'Altitude': u'20'}, 'DistanceParamDestination': {'Longitude': u'40', 'Latitude': u'55', 'Altitude': u'20'}})

Logging

Logs are a useful way of monitoring communications on Symbian devices. Be it a call, a message or data sent over the Internet, a record of it is kept in the phone's Logs application.

As part of the scriptext module, the Logging service API offers greater control over the information in the device's logs than the logs module because it also gives you the ability to add and delete events, not just read them.

As shown in the figure below, Logging provides 4 services: Add, GetList, Delete, and RequestNotification.


Figure 7: Logging Services

The Logging API is loaded as follows:

 
import scriptext
logging_handle = scriptext.load('Service.Logging', 'IDataSource')
 

Add

This service is used to create events in the phone's Logs application. The general form of the handle's call method is call('Add', {'Type': , 'Item': {'EventType': , 'Direction': , 'EventDuration': , 'DeliveryStatus': , 'PhoneNumber': )}}, where appropriate values are to be associated with each parameter. A table containing possible values and descriptions for the parameters is available in the PyS60 documentation. The method returns a unique identifier for the event in the logs database.

Here is an example of how to add a dialed call and a received SMS to the device's logs:

 
import scriptext
 
 
logging_handle = scriptext.load('Service.Logging', 'IDataSource')
 
#The call
log_id = logging_handle.call('Add', {'Type': u'Log', 'Item': {'EventType': 0, 'Direction': 1, 'EventDuration': 20, 'PhoneNumber': u'1234567890'}})
#The line above reads: add a log item consisting of an outgoing (Direction 1) call (EventType 0) that lasted 20 seconds (EventDuration 20) towards the number 1234567890 (PhoneNumber 1234567890)
 
#The SMS
log_id = logging_handle.call('Add', {'Type': u'Log', 'Item': {'EventType': 3, 'Direction': 0, 'DeliveryStatus': 1, 'PhoneNumber': u'1234567890'}})
#This line reads: add a log item consisting of an incoming (Direction 0) SMS (EventType 3) that was successfully sent (DeliveryStatus 1) to the number 1234567890 (PhoneNumber 1234567890)
 

GetList

The GetList service retrieves all the events from the phone's logs as a list of dictionaries. The information in each dictionary can then be accessed by using the name of its field as a key. The mechanism will become clearer after studying the code example below.

 
import scriptext
 
 
logging_handle = scriptext.load('Service.Logging', 'IDataSource')
 
#Get all the entries of type Log
logging_info = logging_handle.call('GetList', {'Type': u'Log',})
#Display their information
for entry in logging_info:
print entry['EventType']
print entry['RemoteParty']
print entry['Direction']
print entry['EventTime']
print entry['Subject']
print entry['PhoneNumber']
print entry['Description']
print entry['EventData']
 

GetList can be used synchronously as well as asynchronously (in this case by adding a callback function as the last paramater of the call method).

Delete

Naturally there might be the need to remove certain events from the log. This is done using Delete:

 
logging_handle.call('Delete', {'Type': u'Log', 'Data': {'id': log_id,}})
#log_id is the ID of the entry we wish to delete
 

RequestNotification

One can be alerted when log entries are added or deleted using the RequestNotification service. It can only be used in asynchronous mode.

 
import scriptext, e32
 
 
app_lock = e32.Ao_lock()
 
def logging_callback(trans_id, event_id, input_params):
#We anticipate the situation in which the request cannot be serviced
if trans_id != logging_id and event_id != scriptext.EventCompleted:
print "Error in servicing the request"
print "Error code is: " + str(input_params["ReturnValue"]["ErrorCode"])
if "ErrorMessage" in input_params["ReturnValue"]:
print "Error message is: " + input_params["ReturnValue"]["ErrorMessage"]
else:
print "Changes notified accordingly"
 
#Continue executing the rest of the script after the request is processed
app_lock.signal()
 
logging_handle = scriptext.load('Service.Logging', 'IDataSource')
logging_id = logging_handle.call('RequestNotification', {'Type': u'Log', 'Filter': {'DelayTime': 600000}}, callback=logging_callback)
 
print "Waiting for the request to be processed"
app_lock.wait()
 
print "Request complete!"
 

Messaging

The Messaging service is, in many ways, a combination of the messaging and inbox modules when it comes to functionality. It allows you to access and delete messages, change their status, and register for new message notifications.


Figure 8: Messaging Services

Send

As the name suggests, Send is a service that enables you to send messages, both SMS and MMS. It can be used synchronously as well as asynchronously.

Here is an example of Send being used synchronously to send an SMS and an MMS with an attachment:

 
import scriptext
 
 
#Load the provider
messaging_handle = scriptext.load('Service.Messaging', 'IMessaging')
 
#Send the SMS
messaging_handle.call('Send', {'MessageType': u'SMS', 'To': u'1234567890', 'BodyText': u'This is the message'})
 
#Send the MMS
messaging_handle.call('Send', {'MessageType': u'MMS', 'To': u'1234567890', 'BodyText': u'This is the message', 'Attachment': u'C:\\Data\\photo.jpg'})
 

As with all the other services, a complete list of parameters for the call method, possible error codes, and their interpretations is available in the PyS60 documentation.

GetList

GetList, available only in synchronous mode, is used to get a list of messaging objects from the messaging center. An object consist of information about one message.

The following code snippet shows how to display the the SMS 'Sender' IDs from all the messages in the inbox:

 
import scriptext
 
 
messaging_handle = scriptext.load('Service.Messaging', 'IMessaging')
 
# This 'GetList' request returns all the SMS in the inbox as an iterable map
sms_iter = messaging_handle.call('GetList', {'Type': u'Inbox'})
 
#Create an empty list which will be populated with the sender IDs
sender_list = []
 
#For every SMS in the inbox, add the sender ID to the list
for sms_dict in sms_iter:
if sms_dict['MessageType'] == 'SMS':
sender_list.append(sms_dict['Sender'])
 
#Display the result
print "ID list :", sender_list
 

RegisterNotification and CancelNotification

Available only in asynchronous mode, RegisterNotification is used to receive notifications for new messages:

 
import scriptext, e32
 
app_lock = e32.Ao_lock()
messaging_handle = scriptext.load('Service.Messaging', 'IMessaging')
 
def new_sms_callback(trans_id, event_id, output_params):
if trans_id == sms_id and event_id == scriptext.EventCompleted:
print "SMS received from" + output_params['ReturnValue']['Sender'])
else:
print "Error in callback"
#Cancel notification request
messaging_handle.call('CancelNotification', {'Type': u'NewMessage'})
app_lock.signal()
 
#The callback 'new_sms_callback' will be called when an SMS is received
sms_id = messaging_handle.call('RegisterNotification', {'Type': u'NewMessage'}, callback=new_sms_callback)
 
app_lock.wait()
 

As we can see from the example above, CancelNotification is used when we wish to stop receiving notifications about new messages.

ChangeStatus

It is sometimes useful to manipulate the status of the messages in the inbox (read/unread). In order to do this, the Messaging service offers ChangeStatus, which can only be used synchronously:

 
import scriptext, appuifw
 
 
messaging_handle = scriptext.load('Service.Messaging', 'IMessaging')
 
sms_iter = messaging_handle.call('GetList', {'Type': u'Inbox'})
id_list = []
body_list = []
#Populate the lists with the IDs and bodies of all the SMS messages
for sms_dict in sms_iter:
if sms_dict['MessageType'] == 'SMS':
id_list.append(sms_dict['MessageId'])
body_list.append(sms_dict['BodyText'])
 
message_index = appuifw.selection_list(body_list)
 
try:
messaging_handle.call('ChangeStatus', {'MessageId': id_list[message_index], 'Status': u'Unread'})
except scriptext.ScriptextError, err:
print "Error setting message status to unread"
else:
print "Message status changed to unread"
 

This displays a list of all the messages in the inbox (their text) and, once the user selects one, changes its status to unread, if possible.

Delete

Delete can be used synchronously to remove a certain message from the inbox:

 
import scriptext, appuifw, e32
 
 
app_lock = e32.Ao_lock()
 
messaging_handle = scriptext.load('Service.Messaging', 'IMessaging')
 
sms_iter = messaging_handle.call('GetList', {'Type': u'Inbox'})
 
id_list = []
body_list = []
for sms_dict in sms_iter:
if sms_dict['MessageType'] == 'SMS':
id_list.append(sms_dict['MessageId'])
body_list.append(sms_dict['BodyText'])
 
#Select the message to be deleted
message_index = appuifw.selection_list(body_list)
 
try:
messaging_handle.call('Delete', {'MessageId': id_list[message_index]})
except scriptext.ScriptextError, err:
print "Error deleting SMS :", err
else:
print "Message deleted successfully"
 

Media Management

A Python application can get information about the media files in the phone's gallery with the Media Management service.

GetList

This service returns the metadata of the media files based on the input parameters. It is only available in asynchronous mode.

As an example, this code snippet shows how to get a list of all MP3 files:

 
import scriptext, e32
 
 
def media_callback(trans_id, event_id, output_params):
if trans_id == media_trans_id:
if event_id == scriptext.EventCompleted:
song_list = []
for item in output_params['ReturnValue']:
song_list.append(item['FileName'])
print "List of files retrieved:", song_list
else:
print "Event ID was not EventCompleted"
else:
print "Invalid Transaction ID"
app_lock.signal()
 
app_lock = e32.Ao_lock()
media_handle = scriptext.load('Service.MediaManagement', 'IDataSource')
 
#Request for the list of MP3s in ascending order
media_trans_id = media_handle.call('GetList', {'Type': u'FileInfo',
'Filter': {'FileType': u'Music',
'Key': u'FileExtension',
'StartRange': u'.mp3'},
'Sort': {'Key': u'FileName',
'Order': u'Ascending'}},
callback=media_callback)
 

A complete list of key values that can be used to filter information is available in the PyS60 documentation.

Sensors


Figure 9: Sensors Services

Sys Info


Figure 10: Sys Info Services

Sign in to comment…