Location Service API example

This section presents the full source code of a working sample widget for the Location Service. You can download the wgz package for this widget from section Introduction to STEW.

For general information about creating widgets, see section Widget component files.

For widget development and debugging purposes, this example writes its output to c:\data\jslog_widget.log using console.info. For instructions on how to enable logging in the Web browser for S60, see section JavaScript console.

Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Nokia//DTD PLIST 1.0//EN" "http://www.nokia.com/NOKIA_COM_1/DTDs/plist-1.0.dtd">
<plist version="1.0">
<dict>
  <key>DisplayName</key>
  <string>LocationSample</string>
  <key>Identifier</key>
  <string>com.nokia.widget.sapi.contact.sample</string>
  <key>Version</key>
  <string>1.0</string>
  <key>MainHTML</key>
  <string>location-sample.html</string>
</dict>
</plist>

location-sample.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <script type="text/javascript" src="js/common.js"></script>
    <script type="text/javascript" src="js/location-sample.js"></script>
  </head>
  <body id='docBody' bgcolor="#ddeeff" onload="setup()" style=width:100%;height:100%;>

    <form name="frm">
      <h3>Location API Sample Widget</h3>

      <input type="button" onclick="getLocation('img1')" value="GetLocation"><img id="img1" src="pic/blank.png" width="25" height="25" align="center"><br>
      <input type="button" onclick="getLocationAsync('img2')" value="GetLocationAsync"><img id="img2" src="pic/blank.png" width="25" height="25" align="center"><br>
      <input type="button" onclick="traceLocation('img3')" value="Trace"><img id="img3" src="pic/blank.png" width="25" height="25" align="center"><br>
      <input type="button" onclick="cancelNotification('img4')" value="CancelNotification"><img id="img4" src="pic/blank.png" width="25" height="25" align="center"><br>
      <input type="button" onclick="calculateLocation('img5')" value="Calculate"><img id="img5" src="pic/blank.png" width="25" height="25" align="center"><br>

      <hr>

      <div class='locationsample' id='locationsample' bgcolor="#ddeeff" style=width:100%;height:100%;overflow:auto></div>

    </form>

  </body>
</html>

common.js

// common.js
//
// This file contains some utility functions

// Check the error code and show the information to users
function checkError(message, resultList, divId, imgId)
{
  var errCode = resultList.ErrorCode;
  var msg = "";

  if (errCode) {
    msg = message + "<BR>" + "Failed Error: " + errCode + "<BR>";
    if(resultList.ErrorMessage != undefined)
      msg += "Error Message: " + resultList.ErrorMessage;
    showIMG(imgId,"no"); 
  } else {
    showIMG(imgId,"yes"); 
  }

  //print error message
  if(divId != null && divId != undefined)
    document.getElementById(divId).innerHTML = msg;
  console.info(msg);

  return errCode;
}

// Build the message by reading a iteratorable list in a recursive manner
function showIterableList(iterator)
{
  var msg = "";
  try
  {
    iterator.reset();
    var item;
    while (( item = iterator.getNext()) != undefined ){
      msg += showObject( item );
    }
  }
  catch(e)
  {
    alert('<showIterableList> ' + e);
  }
  return msg;
}

// Build the message by reading a JS object in a recursive manner
function showObject( obj )
{
  var txt = "";
  try { 
    if ( typeof obj != 'object' )
      return "" + obj + '<BR/>';
    else {
      for(var key in obj) {
        txt +=  key + ":";
        txt += showObject( obj[key] );
        txt += '<BR/>';
      }
      txt += '<BR/>';
    }
  }
  catch (e)
  {
    alert("showObject: " + e);
  }
  return txt;
}

// Show the image to indicate the test result
function showIMG(imgId, isOK) 
{
  if(imgId == null || imgId == undefined)
    return;

  if(isOK == "yes")
    document.getElementById(imgId).src = "pic/yes.png";
  else if(isOK == "no")
    document.getElementById(imgId).src = "pic/no.png";
  else
    document.getElementById(imgId).src = "pic/blank.png";
}

// Show elements in object by using 'alert'
function testObject(obj)
{
  var msg = "";
  for(var key in obj) {
    msg = msg + ":" + key + "=" + obj[key];
  }
  alert(msg);
}

// Test whether the input is numeric
function IsNumeric(sText)
{
  var ValidChars = "0123456789.";
  var IsNumber=true;
  var Char;

  for (i = 0; i < sText.length && IsNumber == true; i++) 
  {
    Char = sText.charAt(i); 
    if (ValidChars.indexOf(Char) == -1) 
    {
      IsNumber = false;
    }
  }
  return IsNumber; 
}

location-sample.js

// location-sample.js
// 
// In this sample Location will be listed, traced, and calculated. 
// Also, Also, async operation will be canceled.
//

//SAPI Error Codes
// 0  - Success
// 1000 - InvalidServiceArgument
// 1001 - UnknownArgumentName
// 1002 - BadArgumentType
// 1003 - MissingArgument
// 1004 - ServiceNotSupported
// 1005 - ServiceInUse
// 1006 - ServiceNotReady
// 1007 - NoMemory
// 1008 - HardwareNotAvailable
// 1009 - ServerBusy
// 1010 - EntryExists
// 1011 - AccessDenied
// 1012 - NotFound
// 1013 - UnknownFormat
// 1014 - GeneralError
// 1015 - CancelSuccess
// 1016 - ServiceTimedOut
// 1017 - PathNotFound

// Declare the service object 
var so;

// imgid for callback1 function
var imgid_callback1;

// imgid for callback2 function
var imgid_callback2;

// id of the div used to display information
const DIV_ID = 'locationsample';

// Called from onload()
function setup()
{
  try {
    so = device.getServiceObject("Service.Location", "ILocation");
    console.info("setup: so: %s", so);
  }
  catch (e) {
    alert('<setup> ' +e);
  }
}

// Get Location
function getLocation(imgId) {

  // This specifies update option used while retrieving location estimation. 
  var updateoptions = new Object();
  // Setting PartialUpdates to 'FALSE' ensures that user get atleast 
  // BasicLocationInformation (Longitude, Lattitude, and Altitude.)
  updateoptions.PartialUpdates = false;

  var criteria = new Object();
  criteria.LocationInformationClass = "GenericLocationInfo";
  criteria.Updateoptions = updateoptions;

  try {
    var result = so.ILocation.GetLocation(criteria);
    if(!checkError("ILocation::getLocation",result,DIV_ID,imgId)) {
      document.getElementById(DIV_ID).innerHTML = showObject(result.ReturnValue);
    }
  }
  catch (e) {
    showIMG(imgId,"no");
    alert ("getLocation: " + e);
  }
}

// Get Location Async
function getLocationAsync(imgId) {

  // This specifies update option used while retrieving location estimation. 
  var updateoptions = new Object();
  // Setting PartialUpdates to 'FALSE' ensures that user get atleast 
  // BasicLocationInformation (Longitude, Lattitude, and Altitude.)
  updateoptions.PartialUpdates = false;

  var criteria = new Object();
  criteria.LocationInformationClass = "GenericLocationInfo";
  criteria.Updateoptions = updateoptions;

  // Set image id for callback1 function
  imgid_callback1 = imgId;

  try {
    var result = so.ILocation.GetLocation(criteria, callback1);
    if(!checkError("ILocation::getLocationAsync",result,DIV_ID,imgId)) {
      showIMG(imgId,"");
    }
  }
  catch (e) {
    showIMG(imgId,"no");
    alert ("getLocationAsync: " + e);
  }
}

// Trace Location
function traceLocation(imgId) {

  // This specifies update option used while retrieving location estimation. 
  var updateoptions = new Object();
  // Setting PartialUpdates to 'FALSE' ensures that user get atleast 
  // BasicLocationInformation (Longitude, Lattitude, and Altitude.)
  updateoptions.PartialUpdates = false;

  var criteria = new Object();
  criteria.LocationInformationClass = "GenericLocationInfo";
  criteria.Updateoptions = updateoptions;

  // Set image id for callback2 function
  imgid_callback2 = imgId;

  try {
    var result = so.ILocation.Trace(criteria, callback2);
    if(!checkError("ILocation::traceLocation",result,DIV_ID,imgId)) {
      showIMG(imgId,"");
    }
  }
  catch (e) {
    showIMG(imgId,"no");
    alert ("traceLocation: " + e);
  }
}

// Cancel Notification
function cancelNotification(imgId) {

  // "TraceCancel"
  // "GetLocCancel"
  var msg = "Please enter the type ['GetLocCancel' or 'TraceCancel']";
  var cancelRequestType = prompt(msg, "TraceCancel");

  if(cancelRequestType == "" || cancelRequestType == null)
    return;

  var criteria = new Object();
  criteria.CancelRequestType = cancelRequestType;

  try {
    var result = so.ILocation.CancelNotification(criteria);
    checkError("ILocation::cancelNotification",result,DIV_ID,imgId);   
  }
  catch (e) {
    showIMG(imgId,"no");
    alert ("cancelNotification: " + e);
  }
}

// Calculate Location
function calculateLocation(imgId) {

  // "FindDistance"
  // "FindBearingTo"
  // "MoveCoordinates"
  var msg = "enter ['FindDistance' or 'FindBearingTo' or 'MoveCoordinates']";
  var mathRequest = prompt(msg, "FindDistance");
  
  if(mathRequest == "" || mathRequest == null)
    return;

  var distanceSrc = new Object();
  distanceSrc.Latitude = 40.69;
  distanceSrc.Longitude = 74.04; 
  distanceSrc.Altitude = 59;

  var distanceDest = new Object();
  distanceDest.Latitude = 42.48;
  distanceDest.Longitude = 71.19;
  distanceDest.Altitude = 2;

  var criteria = new Object();
  criteria.MathRequest = mathRequest;
  criteria.DistanceParamSource = distanceSrc;
  criteria.DistanceParamDestination = distanceDest;
  // The two parameters below are applicable only for Move coordinates (not for Find Distance and Find Bearing)
  criteria.MoveByThisDistance = 10.0;
  criteria.MoveByThisBearing = 10.0;

  try {
    var result = so.ILocation.Calculate(criteria);
    if(!checkError("ILocation::Calculate",result,DIV_ID,imgId)) {
      document.getElementById(DIV_ID).innerHTML = showObject(result.ReturnValue);
    }
  }
  catch (e) {
    showIMG(imgId,"no");
    alert ("calculateLocation: " + e);
  }
}

// This is the asynchronous callback handler 
function callback1(transId, eventCode, result)
{
  console.info("getLocationAsync: transId: %d  eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
  if(!checkError("ILocation::getLocationAsync",result,DIV_ID,imgid_callback1)) {
    document.getElementById(DIV_ID).innerHTML = showObject(result.ReturnValue);
  }
}

// This is the asynchronous callback handler 
function callback2(transId, eventCode, result)
{
  console.info("traceLocation: transId: %d eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
  if(!checkError("ILocation::traceLocation",result,DIV_ID,imgid_callback2)) {
    document.getElementById(DIV_ID).innerHTML = showObject(result.ReturnValue);
  }
}