This page was last modified 13:41, 10 March 2008.
How to utilize device resources from a WRT widget
From Forum Nokia Wiki
The System Info Service API provides access to a limited set of functionality and properties on a compatible S60 device. The current WRT implementation runs in a tight security sandbox and doesn't expose other access to system resources.
While waiting for an updated WRT release, providing access to more system resources, one method to provide some deeper system integration is to run a web server locally on your device and utilize scripting languages (Python, PHP) or native C++ applications to communicate with your WRT widget.
The simplest approach is to use either Mobile Web Server [1] or PAMP [2]as your web server to provide an environment suitable for hosting your scripts.
All of the code snippets and examples in this article will assume that you have PAMP successfully installed and running on your WRT widget compatible device, with your htdocs folder residing on the e-drive.
Contents |
Python scripts
You may run Python scripts hosted under a PAMP or MWS Apache installation by following the guidelines in the MWS documentation [3].
The S60 Platform Security restrictions make the calls to the location related information unaccessible when a script is invoked under the Apache installation.
PHP scripts
The PHP S60 API documentation [4] is still a little shallow in information, but it's a good start for adventurous developers.
Creating a simple SMS sender widget
Create the Python script
The script below sends an SMS message after reading the message recipient number and message contents from the http query string.
I saved my string as test.py. Please keep this in mind when creating your ht.acl file in the next step.
"file test.py" def handler(req): from mod_python import apache, util import messaging req.content_type = 'text/plain' req.encoding = "UTF-8" request_data = util.FieldStorage(req) try: number = request_data.getfirst("number") message = request_data.getfirst("message") messaging.sms_send(number, message) req.write( "succeeded" ) except KeyError: number = None message = None req.write("failed") return apache.OK
Define the handler information for the mod_python page
Create a ht.acl file with the contents similar to the following:
AddHandler mod_python .py
PythonHandler test
PythonDebug On
Options None
Order Deny,Allow
Allow from all
<FilesMatch "\.(pyc|psp)$">
Deny from all
</FilesMatch>
Copy the files to your PAMP installation document root
You can copy the .py and .acl files manually to e:\Data\apache\htdocs\PAMPsmsSender\ or e.g. create a sis-package to do the trick.
Create your WRT widget
Please check the Forum Nokia WRT widget documentation [5] for info on how to create a simple WRT widget.
The Javascript stuff needed for communicating with the Python script shown above is simple.
I use the soon to be released WRTKit bundle to add components and command handlers to my widget UI, but you may naturally implement your UI anyway you like.
Define the URL to your Python script
var PY_URL = "http://127.0.0.1/PAMPsmsSender/.py?";
Introduce some constants for the WRTKit UI manager, main view and the necessary UI components.
Build the UI and add a command handler to the Send button.
// Reference to the WRTKit user interface manager and main view. var uiManager; var mainView; // Reference to controls in the main view. var sendButton; var numberField; var messageField; // Called from the onload event handler to initialize the widget. function init() { // set tab-navigation mode and show softkeys // (only if we are in the WRT environment) if (window.widget) { widget.setNavigationEnabled(false); menu.showSoftkeys(); } // create UI manager uiManager = new UIManager(); // create main view mainView = new ListView(null, "Send an SMS"); // add a text field to the view numberField = new TextField(null, "Recipient"); mainView.addControl(numberField); // add a text field to the view messageField = new TextArea(null, "Message"); mainView.addControl(messageField); // add a button to the view sendButton = new FormButton(null, "Send"); sendButton.addEventListener("ActionPerformed", sendButtonClicked); mainView.addControl(sendButton); // display the main view uiManager.setView(mainView); } function sendButtonClicked(event){ var number = numberField.getText(); var msg = messageField.getText(); if (number.length == "") { uiManager.showNotification(2000, "warning", "Enter recipient number!"); } else if (msg.length == "") { uiManager.showNotification(2000, "warning", "Enter message text!"); } else { sendMsg(); } }
Add code to issue a request to the Python script and handle the progress of the request
function sendMsg() { uiManager.showNotification(-1, "wait", "Sending...", -1); var req = createXMLHttpRequest(); if (req) { var params = "number="+numberField.getText()+"&message="+messageField.getText(); var url = PY_URL + params; loadXMLDoc(req, url); } } // Creates an XMLHttpRequest object function createXMLHttpRequest() { var req = null; try { req = new XMLHttpRequest(); // Make sure that the browser supports overrideMimeType if (typeof req.overrideMimeType != "undefined") { req.overrideMimeType("text/html"); } } catch (ex) { req = null; } return req; } // Loads target XML document (url) into XMLHttpRequest function loadXMLDoc(req, url) { // Register a callback function which gets called when the request state changes req.onreadystatechange = function() { processStateChange(req); }; req.open("GET", url, true); // Transmit the request req.send(null); } // Processes state changes of XMLHttpRequest function processStateChange(req) { // Request states are 0 through 4, where 4 equals complete if (req.readyState == 4) { if (req.status == 200) { uiManager.hideNotification(); showStatus(); } } } function showStatus(req) { uiManager.showNotification(3000, "info", "Message sending "+req.responseText); }
The beef in all of this is issuing an XMLHttpRequest to the Python script with the correct query string.
Reading the messages from Inbox
The messages from your device inbox may be read with either Python or PHP. The Python script is installed in a similar fashion as in the SMS sender case above.
The PHP script may be copied manually or via sis-file installation to a suitable folder under the Apache htdocs-folder.
The code snippets do a bit of HTML-formatting but you may want to recreate the response contents to suit your needs better.
Python
"file test.py" def handler(req): from mod_python import apache import inbox from time import ctime req.content_type = 'text/html' req.encoding = "UTF-8" i = inbox.Inbox() m = i.sms_messages() # all message ID's req.write("<div class=\"messagelist\" id=\"smslistdiv\">") for s in m: req.write("<p class=\"msgheader\" id=\"header_") req.write(str(s)) req.write("\">") req.write(ctime(i.time(s))) req.write(" - ") req.write(i.address(s)) req.write("</p>") req.write("<p class=\"msgtext\" id=\"body_") req.write(str(s)) req.write("\">") req.write(i.content(s).encode("utf-8")) req.write("</p>") req.write("</div>") return apache.OK
PHP
<?php print "<div class=\"messagelist\" id=\"smslistdiv\">"; foreach (s60_inbox_get_messages() as $msg) { print "<p class=\"msgheader\">"; print 'From: '.$msg->sender()."<br/>\n"; print 'When: '.strftime ("%x %X", $msg->time())."<br/>\n"; print "</p>"; print "<p class=\"msgtext\">"; print 'Content: '.$msg->content()."<br/>\n"; print "</p>"; } print "</div>"; ?>
Widget HTML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="StyleSheet" href="styles/general.css" type="text/css" />
<script type="text/javascript" src="scripts/scripts.js" />
<title>Inbox messages</title>
</head>
<body id="body">
<div id="contents"></div>
</body>
</html>
Widget JavaScript
window.onload = init; var PY_SCRIPT_URL = "http://127.0.0.1/inboxTest/.py"; var PHP_SCRIPT_URL = "http://127.0.0.1/inboxTest/inboxtest.php"; var PY_MENU_ITEM_ID = 993; var PHP_MENU_ITEM_ID = 994; // Initializes the widget function init() { window.menu.showSoftkeys(); window.widget.setNavigationEnabled( false ); createMenu(); } function getMsgs( id ) { var requrl; switch (id) { case PY_MENU_ITEM_ID: requrl = PY_SCRIPT_URL; alert("Calling Python script"); break; case PHP_MENU_ITEM_ID: alert("Calling PHP script"); requrl = PHP_SCRIPT_URL; break; } var req = createXMLHttpRequest(); if (req) { loadXMLDoc(req, requrl); } } // Creates an XMLHttpRequest object function createXMLHttpRequest() { var req = null; try { req = new XMLHttpRequest(); if (typeof req.overrideMimeType != "undefined") { req.overrideMimeType("text/html"); } } catch (ex) { req = null; } return req; } // Loads target XML document (url) into XMLHttpRequest function loadXMLDoc(req, url) { // Register a callback function which gets called when the request state changes req.onreadystatechange = function() { processStateChange(req); }; req.open("GET", url, true); // Transmit the request req.send(null); } // Processes state changes of XMLHttpRequest function processStateChange(req) { // Request states are 0 through 4, where 4 equals complete if (req.readyState == 4) { if (req.status == 200) { showList(req); } } } function showList(req) { widget.prepareForTransition("fade"); var mybody = document.getElementById("contents"); mybody.innerHTML = req.responseText; widget.performTransition(); } function createMenu(){ var menu1 = new MenuItem("Fetch using Python", PY_MENU_ITEM_ID); var menu2 = new MenuItem("Fetch using PHP", PHP_MENU_ITEM_ID); menu1.onSelect = getMsgs; menu2.onSelect = getMsgs; window.menu.append(menu1); window.menu.append(menu2); }
Known issues, tips, tricks, AOB
PAMP / MWS has to be restarted before executing a different Python script.
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Please help me for error code 46 | aamitgupta | General Symbian C++ | 9 | 2007-12-01 14:00 |
| flip image horizontally | flicker82 | Symbian User Interface | 2 | 2004-09-07 02:35 |
| how to send file from one phone to another? | sumn79 | General Symbian C++ | 4 | 2004-04-07 09:00 |
| Porting to 3rd Edition : BaseConstructL crashes! | lazmous | Porting Symbian C++ to S60 | 6 | 2006-11-03 10:38 |
| Socket usage throws a security exception on Nokia devices. | tamboss2 | Mobile Java Networking & Messaging & Security | 4 | 2005-09-01 16:24 |
