You Are Here:

Community: Wiki

This page was last modified on 10 March 2008, at 13:41.

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 Wiki Articles

No related wiki articles found

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2010 Nokia 
RDF Facets: qdcZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qdcZidentifierQSxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2findeE78E2ephpE2fHowE5ftoE5fuseE5fE52E44ebugX qdcZpublisherQUxhttpE3aE2fE2fswE2enokiaE2ecomE2fidE2fc764fd1cE2d8b06E2d499aE2d9a6aE2d17c3903d5a65E2fforumE5fnokiaE5fcrawlerE5fagentX qdcZtitleQSxHowE20toE20useE20E52E44ebugE20E2dE20ForumE20NokiaE20WikiX qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfnTypeZCommunityContentQ qdcZtypeQUqfnTypeZE52esourceQ qdcZtypeQUqfnTypeZWebpageQ qdcZtypeQUqfnTypeZWikiContentQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qrssZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qfnZdistributionQUxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2fX qfnZtypeQUqfnTypeZCommunityContentQ qfnZtypeQUqfnTypeZE52esourceQ qfnZtypeQUqfnTypeZWebpageQ qfnZtypeQUqfnTypeZWikiContentQ qfnZupdatedQDx2008E2d10E2d03X qmarsZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfnTypeZCommunityContentQ qrdfZtypeQUqfnTypeZE52esourceQ qrdfZtypeQUqfnTypeZWebpageQ qrdfZtypeQUqfnTypeZWikiContentQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ