|
1 if (typeof(DeviceInfo) != 'object') |
|
2 DeviceInfo = {}; |
|
3 |
|
4 /** |
|
5 * This represents the PhoneGap API itself, and provides a global namespace for accessing |
|
6 * information about the state of PhoneGap. |
|
7 * @class |
|
8 */ |
|
9 PhoneGap = { |
|
10 queue: { |
|
11 ready: true, |
|
12 commands: [], |
|
13 timer: null |
|
14 }, |
|
15 _constructors: [] |
|
16 }; |
|
17 |
|
18 /** |
|
19 * Boolean flag indicating if the PhoneGap API is available and initialized. |
|
20 */ |
|
21 PhoneGap.available = DeviceInfo.uuid != undefined; |
|
22 |
|
23 /** |
|
24 * Execute a PhoneGap command in a queued fashion, to ensure commands do not |
|
25 * execute with any race conditions, and only run when PhoneGap is ready to |
|
26 * recieve them. |
|
27 * @param {String} command Command to be run in PhoneGap, e.g. "ClassName.method" |
|
28 * @param {String[]} [args] Zero or more arguments to pass to the method |
|
29 */ |
|
30 PhoneGap.exec = function() { |
|
31 PhoneGap.queue.commands.push(arguments); |
|
32 if (PhoneGap.queue.timer == null) |
|
33 PhoneGap.queue.timer = setInterval(PhoneGap.run_command, 10); |
|
34 }; |
|
35 /** |
|
36 * Internal function used to dispatch the request to PhoneGap. This needs to be implemented per-platform to |
|
37 * ensure that methods are called on the phone in a way appropriate for that device. |
|
38 * @private |
|
39 */ |
|
40 PhoneGap.run_command = function() { |
|
41 }; |
|
42 |
|
43 /** |
|
44 * This class contains acceleration information |
|
45 * @constructor |
|
46 * @param {Number} x The force applied by the device in the x-axis. |
|
47 * @param {Number} y The force applied by the device in the y-axis. |
|
48 * @param {Number} z The force applied by the device in the z-axis. |
|
49 */ |
|
50 function Acceleration(x, y, z) { |
|
51 /** |
|
52 * The force applied by the device in the x-axis. |
|
53 */ |
|
54 this.x = x; |
|
55 /** |
|
56 * The force applied by the device in the y-axis. |
|
57 */ |
|
58 this.y = y; |
|
59 /** |
|
60 * The force applied by the device in the z-axis. |
|
61 */ |
|
62 this.z = z; |
|
63 /** |
|
64 * The time that the acceleration was obtained. |
|
65 */ |
|
66 this.timestamp = new Date().getTime(); |
|
67 } |
|
68 |
|
69 /** |
|
70 * This class specifies the options for requesting acceleration data. |
|
71 * @constructor |
|
72 */ |
|
73 function AccelerationOptions() { |
|
74 /** |
|
75 * The timeout after which if acceleration data cannot be obtained the errorCallback |
|
76 * is called. |
|
77 */ |
|
78 this.timeout = 10000; |
|
79 } |
|
80 /** |
|
81 * This class provides access to device accelerometer data. |
|
82 * @constructor |
|
83 */ |
|
84 function Accelerometer() { |
|
85 /** |
|
86 * The last known acceleration. |
|
87 */ |
|
88 this.lastAcceleration = null; |
|
89 } |
|
90 |
|
91 /** |
|
92 * Asynchronously aquires the current acceleration. |
|
93 * @param {Function} successCallback The function to call when the acceleration |
|
94 * data is available |
|
95 * @param {Function} errorCallback The function to call when there is an error |
|
96 * getting the acceleration data. |
|
97 * @param {AccelerationOptions} options The options for getting the accelerometer data |
|
98 * such as timeout. |
|
99 */ |
|
100 |
|
101 Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) { |
|
102 // If the acceleration is available then call success |
|
103 // If the acceleration is not available then call error |
|
104 |
|
105 try { |
|
106 if (!this.serviceObj) |
|
107 this.serviceObj = this.getServiceObj(); |
|
108 |
|
109 if (this.serviceObj == null) |
|
110 throw { |
|
111 name: "DeviceErr", |
|
112 message: "Could not initialize service object" |
|
113 }; |
|
114 |
|
115 //get the sensor channel |
|
116 var SensorParams = { |
|
117 SearchCriterion: "AccelerometerAxis" |
|
118 }; |
|
119 var returnvalue = this.serviceObj.ISensor.FindSensorChannel(SensorParams); |
|
120 var error = returnvalue["ErrorCode"]; |
|
121 var errmsg = returnvalue["ErrorMessage"]; |
|
122 if (!(error == 0 || error == 1012)) { |
|
123 var ex = { |
|
124 name: "Unable to find Sensor Channel: " + error, |
|
125 message: errmsg |
|
126 }; |
|
127 throw ex; |
|
128 } |
|
129 var channelInfoMap = returnvalue["ReturnValue"][0]; |
|
130 var criteria = { |
|
131 ChannelInfoMap: channelInfoMap, |
|
132 ListeningType: "ChannelData" |
|
133 }; |
|
134 |
|
135 if (typeof(successCallback) != 'function') |
|
136 successCallback = function(){ |
|
137 }; |
|
138 if (typeof(errorCallback) != 'function') |
|
139 errorCallback = function(){ |
|
140 }; |
|
141 |
|
142 this.success_callback = successCallback; |
|
143 this.error_callback = errorCallback; |
|
144 //create a closure to persist this instance of Accelerometer into the RegisterForNofication callback |
|
145 var obj = this; |
|
146 |
|
147 // TODO: this call crashes WRT, but there is no other way to read the accel sensor |
|
148 // http://discussion.forum.nokia.com/forum/showthread.php?t=182151&highlight=memory+leak |
|
149 this.serviceObj.ISensor.RegisterForNotification(criteria, function(transId, eventCode, result){ |
|
150 try { |
|
151 var criteria = { |
|
152 TransactionID: transId |
|
153 }; |
|
154 obj.serviceObj.ISensor.Cancel(criteria); |
|
155 |
|
156 var accel = new Acceleration(result.ReturnValue.XAxisData, result.ReturnValue.YAxisData, result.ReturnValue.ZAxisData); |
|
157 Accelerometer.lastAcceleration = accel; |
|
158 |
|
159 obj.success_callback(accel); |
|
160 |
|
161 } |
|
162 catch (ex) { |
|
163 obj.serviceObj.ISensor.Cancel(criteria); |
|
164 obj.error_callback(ex); |
|
165 } |
|
166 |
|
167 }); |
|
168 } catch (ex) { |
|
169 errorCallback(ex); |
|
170 } |
|
171 |
|
172 }; |
|
173 |
|
174 |
|
175 /** |
|
176 * Asynchronously aquires the acceleration repeatedly at a given interval. |
|
177 * @param {Function} successCallback The function to call each time the acceleration |
|
178 * data is available |
|
179 * @param {Function} errorCallback The function to call when there is an error |
|
180 * getting the acceleration data. |
|
181 * @param {AccelerationOptions} options The options for getting the accelerometer data |
|
182 * such as timeout. |
|
183 */ |
|
184 |
|
185 Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) { |
|
186 this.getCurrentAcceleration(successCallback, errorCallback, options); |
|
187 // TODO: add the interval id to a list so we can clear all watches |
|
188 var frequency = (options != undefined)? options.frequency : 10000; |
|
189 return setInterval(function() { |
|
190 navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options); |
|
191 }, frequency); |
|
192 }; |
|
193 |
|
194 /** |
|
195 * Clears the specified accelerometer watch. |
|
196 * @param {String} watchId The ID of the watch returned from #watchAcceleration. |
|
197 */ |
|
198 Accelerometer.prototype.clearWatch = function(watchId) { |
|
199 clearInterval(watchId); |
|
200 }; |
|
201 |
|
202 //gets the Acceleration Service Object from WRT |
|
203 Accelerometer.prototype.getServiceObj = function() { |
|
204 var so; |
|
205 |
|
206 try { |
|
207 so = device.getServiceObject("Service.Sensor", "ISensor"); |
|
208 } catch (ex) { |
|
209 throw { |
|
210 name: "DeviceError", |
|
211 message: "Could not initialize accel service object (" + ex.name + ": " + ex.message + ")" |
|
212 }; |
|
213 } |
|
214 return so; |
|
215 }; |
|
216 |
|
217 if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer();/** |
|
218 * This class provides access to the device media, interfaces to both sound and video |
|
219 * @constructor |
|
220 */ |
|
221 function Audio(src, successCallback, errorCallback) { |
|
222 this.src = src; |
|
223 this.successCallback = successCallback; |
|
224 this.errorCallback = errorCallback; |
|
225 } |
|
226 |
|
227 Audio.prototype.record = function() { |
|
228 }; |
|
229 |
|
230 Audio.prototype.play = function() { |
|
231 try { |
|
232 if (document.getElementById('gapsound')) |
|
233 document.body.removeChild(document.getElementById('gapsound')); |
|
234 var obj; |
|
235 obj = document.createElement("embed"); |
|
236 obj.setAttribute("id", "gapsound"); |
|
237 obj.setAttribute("type", "audio/x-mpeg"); |
|
238 obj.setAttribute("width", "0"); |
|
239 obj.setAttribute("width", "0"); |
|
240 obj.setAttribute("hidden", "true"); |
|
241 obj.setAttribute("autostart", "true"); |
|
242 obj.setAttribute("src", this.src); |
|
243 document.body.appendChild(obj); |
|
244 } catch (ex) { debug.log(ex.name + ": " + ex.message); } |
|
245 }; |
|
246 |
|
247 Audio.prototype.pause = function() { |
|
248 }; |
|
249 |
|
250 Audio.prototype.stop = function() { |
|
251 document.body.removeChild(document.getElementById('gapsound')); |
|
252 }; |
|
253 /** |
|
254 * This class provides access to the device camera. |
|
255 * @constructor |
|
256 */ |
|
257 function Camera() { |
|
258 this.success_callback = null; |
|
259 this.error_callback = null; |
|
260 } |
|
261 |
|
262 /** |
|
263 * We use the Platform Services 2.0 API here. So we must include a portion of the |
|
264 * PS 2.0 source code (camera API). |
|
265 * @param {Function} successCallback |
|
266 * @param {Function} errorCallback |
|
267 * @param {Object} options |
|
268 */ |
|
269 Camera.prototype.getPicture = function(successCallback, errorCallback, options){ |
|
270 try { |
|
271 if (!this.serviceObj) { |
|
272 this.serviceObj = com.nokia.device.load("", "com.nokia.device.camera", ""); |
|
273 } |
|
274 if (!this.serviceObj) { |
|
275 throw { |
|
276 name: "CameraError", |
|
277 message: "could not load camera service" |
|
278 }; |
|
279 } |
|
280 var obj = this; |
|
281 |
|
282 obj.success_callback = successCallback; |
|
283 obj.error_callback = errorCallback; |
|
284 this.serviceObj.startCamera( function(transactionID, errorCode, outPut) { |
|
285 //outPut should be an array of image urls (local), or an error code |
|
286 if (errorCode == 0) { |
|
287 obj.success_callback(outPut); |
|
288 } |
|
289 else { |
|
290 obj.error_callback({ |
|
291 name: "CameraError", |
|
292 message: errorCode |
|
293 }); |
|
294 } |
|
295 }); |
|
296 |
|
297 } catch (ex) { |
|
298 errorCallback.call(ex); |
|
299 } |
|
300 |
|
301 }; |
|
302 |
|
303 if (typeof navigator.camera == "undefined") navigator.camera = new Camera();/* |
|
304 Copyright © 2009 Nokia. All rights reserved. |
|
305 Code licensed under the BSD License: |
|
306 Software License Agreement (BSD License) Copyright © 2009 Nokia. |
|
307 All rights reserved. |
|
308 Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
309 |
|
310 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
311 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
312 Neither the name of Nokia Corporation. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Nokia Corporation. |
|
313 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
314 |
|
315 version: 1.0 |
|
316 */ |
|
317 |
|
318 |
|
319 // utility.js |
|
320 // |
|
321 // This file contains some utility functions for S60 providers |
|
322 |
|
323 |
|
324 // Start an application and wait for it to exit |
|
325 |
|
326 //TBD: Get rid of this global, use closures instead |
|
327 |
|
328 DeviceError.prototype = new Error(); //inheritance occurs here |
|
329 DeviceError.prototype.constructor = DeviceError; //If this not present then, it uses default constructor of Error |
|
330 |
|
331 //constructor for DeviceError. |
|
332 function DeviceError(message,code) |
|
333 { |
|
334 this.toString = concatenate; |
|
335 this.code = code; |
|
336 this.name = "DeviceException";//we can even overwrite default name "Error" |
|
337 this.message=message; |
|
338 } |
|
339 |
|
340 function concatenate() |
|
341 { |
|
342 return (this.name+":"+" "+this.message+" "+this.code); |
|
343 } |
|
344 |
|
345 function splitErrorMessage(errmessage) |
|
346 { |
|
347 if(errmessage.search(/:/)!=-1) |
|
348 { |
|
349 if((errmessage.split(":").length)==2) |
|
350 { |
|
351 return errmessage.split(":")[1]; |
|
352 } |
|
353 if((errmessage.split(":").length)>2) |
|
354 { |
|
355 return errmessage.split(":")[2]; |
|
356 } |
|
357 } |
|
358 return errmessage; |
|
359 } |
|
360 |
|
361 |
|
362 var __s60_start_and_wait_cb; |
|
363 |
|
364 function __s60_on_app_exit(){ |
|
365 widget.onshow = null; |
|
366 if(__s60_start_and_wait_cb != null){ |
|
367 __s60_start_and_wait_cb(); |
|
368 } |
|
369 } |
|
370 |
|
371 function __s60_on_app_start(){ |
|
372 widget.onhide = null; |
|
373 widget.onshow = __s60_on_app_exit; |
|
374 } |
|
375 |
|
376 // This function cannot actually force JS to wait, |
|
377 // but it does supply a callback the apps can use |
|
378 // to continue processing on return from the app. |
|
379 // Apps should take care not to reinvoke this and |
|
380 // should be careful about any other processing |
|
381 // that might happen while the app is running. |
|
382 |
|
383 function __s60_start_and_wait(id, args, app_exit_cb){ |
|
384 __s60_start_and_wait_cb = app_exit_cb; |
|
385 widget.onhide = __s60_on_app_start; |
|
386 widget.openApplication(id, args); |
|
387 } |
|
388 |
|
389 function __s60_api_not_supported(){ |
|
390 throw(err_ServiceNotSupported); |
|
391 } |
|
392 |
|
393 function __s60_enumerate_object(object, namespace, func, param){ |
|
394 var key; |
|
395 for(key in object){ |
|
396 |
|
397 var propname; |
|
398 if(namespace){ |
|
399 propname = namespace + "." + key; |
|
400 } |
|
401 else{ |
|
402 propname = key; |
|
403 } |
|
404 var value = object[key]; |
|
405 if(typeof value == "object"){ |
|
406 __s60_enumerate_object(value, propname, func, param); |
|
407 } |
|
408 else { |
|
409 func(propname,value, param); |
|
410 } |
|
411 } |
|
412 } |
|
413 /* |
|
414 Copyright © 2009 Nokia. All rights reserved. |
|
415 Code licensed under the BSD License: |
|
416 Software License Agreement (BSD License) Copyright © 2009 Nokia. |
|
417 All rights reserved. |
|
418 Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
419 |
|
420 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
421 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
422 Neither the name of Nokia Corporation. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Nokia Corporation. |
|
423 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
424 |
|
425 version: 1.0 |
|
426 */ |
|
427 |
|
428 |
|
429 var __device_debug_on__ = true; |
|
430 var err_missing_argument = 1003; |
|
431 var event_cancelled = 3; |
|
432 var err_bad_argument = 1002; |
|
433 var err_InvalidService_Argument = 1000; |
|
434 var err_ServiceNotReady = 1006; |
|
435 var err_ServiceNotSupported = 1004; |
|
436 |
|
437 function __device_debug(text){ |
|
438 //if(__device_debug_on__) alert(text); |
|
439 } |
|
440 |
|
441 function __device_handle_exception(e, text){ |
|
442 __device_debug(text); |
|
443 throw(e); |
|
444 } |
|
445 |
|
446 function __device_typeof(value) |
|
447 { |
|
448 // First check to see if the value is undefined. |
|
449 if (value == undefined) { |
|
450 return "undefined"; |
|
451 } |
|
452 // Check for objects created with the "new" keyword. |
|
453 if (value instanceof Object) { |
|
454 // Check whether it's a string object. |
|
455 if (value instanceof String) { |
|
456 return "String"; |
|
457 } |
|
458 // Check whether it's an array object/array literal. |
|
459 else |
|
460 if (value instanceof Array) { |
|
461 return "Array"; |
|
462 } |
|
463 } |
|
464 // dealing with a literal. |
|
465 if (typeof value) { |
|
466 if (typeof value == "object") { |
|
467 if (typeof value == "object" && !value) { |
|
468 return "null"; |
|
469 } |
|
470 } |
|
471 // if not null check for other types |
|
472 |
|
473 // Check if it's a string literal. |
|
474 else if (typeof value == "string") { |
|
475 return "string"; |
|
476 } |
|
477 } |
|
478 } |
|
479 |
|
480 |
|
481 // The top-level service object. It would be nice to use a namespace here |
|
482 // (com.nokia.device.service), but emulating namespaces still allows name clashes. |
|
483 /* |
|
484 var sp_device = { |
|
485 //services: null; // TBD: Make the services list a member of this object? |
|
486 load: __device_service_load, |
|
487 listServices: __device_service_list, |
|
488 listInterfaces: __device_service_interfaces, |
|
489 version: "0.1", |
|
490 info: "device prototype" |
|
491 }; |
|
492 */ |
|
493 |
|
494 if(undefined == com) |
|
495 var com={}; |
|
496 |
|
497 if( typeof com != "object") |
|
498 throw("com defined as non object"); |
|
499 |
|
500 if(undefined == com.nokia) |
|
501 com.nokia = {}; |
|
502 |
|
503 if( typeof com.nokia != "object") |
|
504 throw("com.nokia defined as non object"); |
|
505 |
|
506 if(undefined == com.nokia.device) |
|
507 com.nokia.device = { |
|
508 load: __device_service_load, |
|
509 listServices: __device_service_list, |
|
510 listInterfaces: __device_service_interfaces, |
|
511 version: "0.1", |
|
512 info: "device prototype" |
|
513 }; |
|
514 else |
|
515 throw("com.nokia.device already defined"); |
|
516 |
|
517 com.nokia.device.SORT_ASCENDING = 0; |
|
518 com.nokia.device.SORT_DESCENDING = 1; |
|
519 |
|
520 com.nokia.device.SORT_BY_DATE = 0; |
|
521 com.nokia.device.SORT_BY_SENDER = 1; |
|
522 |
|
523 com.nokia.device.STATUS_READ = 0; |
|
524 com.nokia.device.STATUS_UNREAD = 1; |
|
525 |
|
526 |
|
527 // Configure the services offered. |
|
528 |
|
529 var __device_services_inited = false; |
|
530 |
|
531 var __device_services = [ |
|
532 |
|
533 // For now, the only service is the base "device"" service |
|
534 { |
|
535 "name":"com.nokia.device", |
|
536 "version": 0.1, |
|
537 "interfaces": [] |
|
538 } |
|
539 ]; |
|
540 |
|
541 // Initialize the configured services. |
|
542 |
|
543 function __device_services_init(){ |
|
544 if(__device_services_inited){ |
|
545 return; |
|
546 } |
|
547 __device_services_inited = true; |
|
548 |
|
549 // Get the service-specific service entries. Note that these |
|
550 // need to be individually wrapped by try/catch blocks so that the |
|
551 // interpreter gracefully handles missing services. |
|
552 |
|
553 try { |
|
554 __device_services[0].interfaces.push(__device_geolocation_service_entry); |
|
555 }catch (e){ |
|
556 __device_debug("Missing library implementation: " + e); |
|
557 } |
|
558 try { |
|
559 __device_services[0].interfaces.push(__device_camera_service_entry); |
|
560 }catch (e){ |
|
561 __device_debug("Missing library implementation: " + e); |
|
562 } |
|
563 try { |
|
564 __device_services[0].interfaces.push(__device_media_service_entry); |
|
565 }catch (e){ |
|
566 // __device_debug("Missing library implementation: " + e); |
|
567 } |
|
568 try { |
|
569 __device_services[0].interfaces.push(__device_contacts_service_entry); |
|
570 }catch (e){ |
|
571 // __device_debug("Missing library implementation: " + e); |
|
572 } |
|
573 try { |
|
574 __device_services[0].interfaces.push(__device_messaging_service_entry); |
|
575 }catch (e){ |
|
576 __device_debug("Missing library implementation: " + e); |
|
577 } |
|
578 try { |
|
579 __device_services[0].interfaces.push(__device_calendar_service_entry); |
|
580 }catch (e){ |
|
581 __device_debug("Missing library implementation: " + e); |
|
582 } |
|
583 try { |
|
584 __device_services[0].interfaces.push(__device_landmarks_service_entry); |
|
585 }catch (e){ |
|
586 __device_debug("Missing library implementation: " + e); |
|
587 } |
|
588 try { |
|
589 __device_services[0].interfaces.push(__device_event_service_entry); |
|
590 }catch (e){ |
|
591 __device_debug("Missing library implementation: " + e); |
|
592 } |
|
593 try { |
|
594 __device_services[0].interfaces.push(__device_sysinfo_service_entry); |
|
595 }catch (e){ |
|
596 __device_debug("Missing library implementation: " + e); |
|
597 } |
|
598 try { |
|
599 __device_services[0].interfaces.push(__device_sensors_service_entry); |
|
600 }catch (e){ |
|
601 __device_debug("Missing library implementation: " + e); |
|
602 } |
|
603 |
|
604 } |
|
605 |
|
606 function __device_get_implementation(i){ |
|
607 //__device_debug("get_implementation: " + i); |
|
608 return new i.proto(new(i.providers[0].instance)); |
|
609 } |
|
610 |
|
611 function __device_get_descriptor(i){ |
|
612 //__device_debug("get_descriptor: " + i); |
|
613 return new i.descriptor(new(i.providers[0].descriptor)); |
|
614 } |
|
615 |
|
616 function __device_get_interface(s, interfaceName, version){ |
|
617 //__device_debug("get_interface: " + s + " " + interfaceName); |
|
618 var i = s.interfaces; |
|
619 if((interfaceName == null) || (interfaceName == '')){ |
|
620 // Interface name not specified, get first interface, ignoring version |
|
621 return __device_get_implementation(i[0]); |
|
622 } |
|
623 |
|
624 // Find first match of name and version |
|
625 for (var d in i){ |
|
626 |
|
627 if(i[d].name == null){ |
|
628 __device_update_descriptor(i[d]); |
|
629 } |
|
630 if(i[d].name == undefined){ |
|
631 continue; |
|
632 } |
|
633 if (i[d].name == interfaceName){ |
|
634 // Match version if specified |
|
635 if ((version == null) || (version == '') || (i[d].version >= version)){ |
|
636 return __device_get_implementation(i[d]); |
|
637 } |
|
638 } |
|
639 } |
|
640 return null; |
|
641 } |
|
642 |
|
643 // Implemention of the load method |
|
644 |
|
645 function __device_service_load(serviceName, interfaceName, version){ |
|
646 |
|
647 __device_services_init(); |
|
648 |
|
649 // Service name is specified |
|
650 if ((serviceName != null) && (serviceName != '') &&(serviceName != "*")){ |
|
651 for(var s in __device_services){ |
|
652 if (serviceName == __device_services[s].name){ |
|
653 return __device_get_interface(__device_services[s], interfaceName, version); |
|
654 } |
|
655 } |
|
656 // Service name not specified, get first implementation |
|
657 } else { |
|
658 //__device_debug("Trying to get interface implementations: "); |
|
659 for(var s in __device_services){ |
|
660 //__device_debug("service_load: " + s + ":" + __device_services[s].name + ": " + interfaceName); |
|
661 var i = __device_get_interface(__device_services[s], interfaceName, version); |
|
662 if (i != null){ |
|
663 return i; |
|
664 } |
|
665 } |
|
666 } |
|
667 return null; |
|
668 } |
|
669 |
|
670 // Lazily fill in the descriptor table |
|
671 |
|
672 function __device_update_descriptor(i){ |
|
673 var d = __device_get_descriptor(i); |
|
674 i.name = d.interfaceName; |
|
675 i.version = d.version; |
|
676 } |
|
677 // Get an array of interface descriptors for a service |
|
678 |
|
679 function __device_interface_list(s){ |
|
680 var retval = new Array(); |
|
681 for(var i in s.interfaces){ |
|
682 if(s.interfaces[i].name == null){ |
|
683 __device_update_descriptor(s.interfaces[i]); |
|
684 } |
|
685 if(s.interfaces[i].name == undefined){ |
|
686 continue; |
|
687 } |
|
688 retval[i] = new Object(); |
|
689 retval[i].name = s.interfaces[i].name; |
|
690 retval[i].version = s.interfaces[i].version; |
|
691 } |
|
692 return retval; |
|
693 } |
|
694 |
|
695 // Get a service description |
|
696 |
|
697 function __device_service_descriptor(s){ |
|
698 this.name = s.name; |
|
699 this.version = s.version; |
|
700 this.interfaces = __device_interface_list(s); |
|
701 this.toString = __device_service_descriptor_to_string; |
|
702 } |
|
703 |
|
704 function __device_service_descriptor_to_string(){ |
|
705 var is = "\nInterfaces(s): "; |
|
706 |
|
707 for (i in this.interfaces){ |
|
708 is += "\n" + this.interfaces[i].name + " " + this.interfaces[0].version; |
|
709 } |
|
710 return ("Service: " + this.name + is); |
|
711 } |
|
712 |
|
713 // Implement the listServices method |
|
714 |
|
715 function __device_service_list(serviceName, interfaceName, version){ |
|
716 //__device_debug("__device_service_list: " + serviceName + " " + interfaceName); |
|
717 __device_services_init(); |
|
718 var retval = new Array(); |
|
719 var n = 0; |
|
720 |
|
721 //Treat empty service and interface names as wildcards |
|
722 if ((serviceName == null)|| (serviceName == '')/* || (serviceName == undefined)*/){ |
|
723 serviceName = ".*"; |
|
724 } |
|
725 if ((interfaceName == null) || (interfaceName == '') /*|| (serviceName == undefined)*/){ |
|
726 interfaceName = ".*"; |
|
727 } |
|
728 |
|
729 if ((typeof serviceName != "string") || (typeof interfaceName != "string")) { |
|
730 return retval; |
|
731 } |
|
732 |
|
733 // This method does regular expression matching of service and interface |
|
734 |
|
735 var sregx = new RegExp(serviceName); |
|
736 var iregx = new RegExp(interfaceName); |
|
737 |
|
738 for(var s in __device_services){ |
|
739 //__device_debug (serviceName + "==" + __device_services[s].name + "?:" + sregx.test(__device_services[s].name)); |
|
740 if (sregx.test(__device_services[s].name)){ |
|
741 // Find the first matching interface |
|
742 |
|
743 for(var i in __device_services[s].interfaces){ |
|
744 if(__device_services[s].interfaces[i].name == null){ |
|
745 __device_update_descriptor(__device_services[s].interfaces[i]); |
|
746 } |
|
747 if(__device_services[s].interfaces[i].name == undefined){ |
|
748 continue; |
|
749 } |
|
750 //__device_debug (interfaceName + "==" + __device_services[s].interfaces[i].name + "?:" + iregx.test(__device_services[s].interfaces[i].name)); |
|
751 if (iregx.test(__device_services[s].interfaces[i].name)){ |
|
752 if ((version == null) || (version == '') || (__device_services[s].interfaces[i].version >= version)){ |
|
753 // An interface matched, we're done. |
|
754 retval[n] = new __device_service_descriptor(__device_services[s]); |
|
755 break; |
|
756 } |
|
757 } |
|
758 } |
|
759 } |
|
760 ++n; |
|
761 } |
|
762 return retval; |
|
763 } |
|
764 |
|
765 // Implement the listInterfaces method |
|
766 |
|
767 function __device_service_interfaces(serviceName){ |
|
768 __device_services_init(); |
|
769 if(serviceName==null||serviceName==undefined||serviceName==''){ |
|
770 throw new DeviceError("Framework: listInterfaces: serviceName is missing", err_missing_argument); |
|
771 } |
|
772 for (var s in __device_services){ |
|
773 if(__device_services[s].name == serviceName){ |
|
774 return __device_interface_list(__device_services[s]); |
|
775 } |
|
776 } |
|
777 return null; |
|
778 } |
|
779 |
|
780 function modifyObjectBaseProp(obj){ |
|
781 for (pro in obj) { |
|
782 if(typeof obj[pro] == "function" ) |
|
783 obj[pro] = 0; |
|
784 } |
|
785 }; |
|
786 /* |
|
787 Copyright © 2009 Nokia. All rights reserved. |
|
788 Code licensed under the BSD License: |
|
789 Software License Agreement (BSD License) Copyright © 2009 Nokia. |
|
790 All rights reserved. |
|
791 Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
792 |
|
793 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
794 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
795 Neither the name of Nokia Corporation. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Nokia Corporation. |
|
796 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
797 |
|
798 version: 1.0 |
|
799 */ |
|
800 |
|
801 |
|
802 // S60 sp-based camera provider |
|
803 |
|
804 function __sp_camera_descriptor(){ |
|
805 //__device_debug("sp_camera_descriptor"); |
|
806 //Read-only properties |
|
807 this.interfaceName = "com.nokia.device.camera"; |
|
808 this.version = "0.1"; |
|
809 //Class-static properties |
|
810 } |
|
811 |
|
812 // TBD make local to closure funcs |
|
813 var __sp_camera_start_date; |
|
814 |
|
815 function __sp_camera_instance(){ |
|
816 //__device_debug("sp_camera_instance"); |
|
817 //Descriptor |
|
818 this.descriptor = new __sp_camera_descriptor(); |
|
819 //Core methods |
|
820 this.startCamera = __sp_startCamera; |
|
821 this.stopViewfinder = __s60_api_not_supported; |
|
822 //Extended methods |
|
823 this.takePicture = __s60_api_not_supported; |
|
824 //Private data |
|
825 } |
|
826 |
|
827 var CAMERA_APP_ID = 0x101f857a; |
|
828 |
|
829 //Apps should take care that this is not reinvoked |
|
830 //while the viewfinder is running. |
|
831 |
|
832 function __sp_startCamera(camera_cb){ |
|
833 |
|
834 //If callback is null , then return missing argument error |
|
835 if( camera_cb == null ) |
|
836 throw new DeviceError("Camera:startCamera:callback is missing", err_missing_argument); |
|
837 |
|
838 //If the callback is not a function, then return bad type error |
|
839 if( typeof(camera_cb) != "function" ) |
|
840 throw new DeviceError("Camera:startCamera:callback is a non-function", err_bad_argument); |
|
841 |
|
842 var finished = function (){ |
|
843 var invoker = function (arg1, arg2, arg3){ |
|
844 //__device_debug("invoker with: " + camera_cb); |
|
845 var it = arg3.ReturnValue; |
|
846 var item; |
|
847 var items = new Array(); |
|
848 while (( item = it.getNext()) != undefined){ |
|
849 var d = new Date(Date.parse(item.FileDate)); |
|
850 //__device_debug(item.FileName + " " + d ); |
|
851 // Items returned in reverse date order, so stop iterating before |
|
852 // reaching initial date. (Should be able to do this more efficiently |
|
853 // with sp filter, but that doesn't seem to work right now.) |
|
854 if (d > __sp_camera_start_date) { |
|
855 var pathname = item.FileNameAndPath.replace(/\\/g, "/"); |
|
856 var fileScheme = "file:///"; |
|
857 //Non-patched builds don't allow file scheme TBD: change this for patched builds |
|
858 items.unshift(fileScheme + pathname); |
|
859 } |
|
860 } |
|
861 var dummyTransID = 0; |
|
862 var dummyStatusCode = 0; |
|
863 camera_cb(dummyTransID, dummyStatusCode, items); |
|
864 }; |
|
865 |
|
866 |
|
867 //When camera returns, get the image(s) created |
|
868 try { |
|
869 var mso = device.getServiceObject("Service.MediaManagement", "IDataSource"); |
|
870 } |
|
871 catch(e) { |
|
872 __device_handle_exception (e, "media service not available : " + e); |
|
873 } |
|
874 |
|
875 var criteria = new Object(); |
|
876 modifyObjectBaseProp(criteria); |
|
877 criteria.Type = 'FileInfo'; |
|
878 criteria.Filter = new Object(); |
|
879 modifyObjectBaseProp(criteria.Filter); |
|
880 criteria.Filter.FileType = 'Image'; |
|
881 //criteria.Filter.Key = 'FileDate'; |
|
882 //criteria.Filter.StartRange = null; |
|
883 //criteria.Filter.EndRange = null; |
|
884 criteria.Sort = new Object(); |
|
885 modifyObjectBaseProp(criteria.Sort); |
|
886 criteria.Sort.Key = 'FileDate'; |
|
887 criteria.Sort.Order = 'Descending'; |
|
888 |
|
889 try { |
|
890 var rval = mso.IDataSource.GetList(criteria, invoker); |
|
891 } |
|
892 catch (e) { |
|
893 __device_handle_exception (e, "media service GetList failed: " + e); |
|
894 } |
|
895 }; |
|
896 |
|
897 __sp_camera_start_date = new Date(); |
|
898 __s60_start_and_wait(CAMERA_APP_ID, "", finished); |
|
899 var dummyTid = 0; |
|
900 return dummyTid; |
|
901 } |
|
902 |
|
903 |
|
904 /* |
|
905 Copyright © 2009 Nokia. All rights reserved. |
|
906 Code licensed under the BSD License: |
|
907 Software License Agreement (BSD License) Copyright © 2009 Nokia. |
|
908 All rights reserved. |
|
909 Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
910 |
|
911 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
912 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
913 Neither the name of Nokia Corporation. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Nokia Corporation. |
|
914 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
915 |
|
916 version: 1.0 |
|
917 */ |
|
918 |
|
919 |
|
920 // Camera service interface |
|
921 |
|
922 var __device_camera_service_entry = {"name": null, |
|
923 "version": null, |
|
924 "proto": __device_camera, |
|
925 "descriptor": __device_camera_descriptor, |
|
926 "providers": [{"descriptor": __sp_camera_descriptor, "instance": __sp_camera_instance}] |
|
927 }; |
|
928 |
|
929 function __device_camera_descriptor(provider){ |
|
930 this.interfaceName = provider.interfaceName; |
|
931 this.version = provider.version; |
|
932 } |
|
933 |
|
934 |
|
935 // Private camera prototype: called from service factory |
|
936 function __device_camera(provider){ |
|
937 //Private properties |
|
938 this.provider = provider; |
|
939 //Read-only properties |
|
940 this.interfaceName = provider.descriptor.interfaceName; |
|
941 this.version = provider.descriptor.version; |
|
942 // this.supportedMediaTypes = provider.supportedMediaTypes; |
|
943 // this.supportedSizes = provider.supportedSizes; |
|
944 //Core methods |
|
945 this.startCamera = __device_camera_startCamera; |
|
946 this.stopViewfinder = __device_camera_stopViewfinder; |
|
947 //Extended methods |
|
948 this.takePicture = __device_camera_takePicture; |
|
949 } |
|
950 |
|
951 |
|
952 //Why bother to define these methods? Because the camera |
|
953 //object defines the contract for providers! |
|
954 |
|
955 function __device_camera_startCamera(camera_cb){ |
|
956 return this.provider.startCamera(camera_cb); |
|
957 } |
|
958 |
|
959 function __device_camera_stopViewfinder(){ |
|
960 this.provider.stopViewfinder(); |
|
961 } |
|
962 |
|
963 function __device_camera_takePicture(format){ |
|
964 this.provider.takePicture(format); |
|
965 } |
|
966 /** |
|
967 * This class provides access to the device contacts. |
|
968 * @constructor |
|
969 */ |
|
970 |
|
971 function Contacts() { |
|
972 |
|
973 } |
|
974 |
|
975 function Contact() { |
|
976 this.id = null; |
|
977 this.name = { |
|
978 formatted: "", |
|
979 givenName: "", |
|
980 familyName: "" |
|
981 }; |
|
982 this.phones = []; |
|
983 this.emails = []; |
|
984 } |
|
985 |
|
986 Contact.prototype.displayName = function() |
|
987 { |
|
988 // TODO: can be tuned according to prefs |
|
989 return this.givenName + " " + this.familyName; |
|
990 }; |
|
991 |
|
992 /* |
|
993 * @param {ContactsFilter} filter Object with filter properties. filter.name only for now. |
|
994 * @param {function} successCallback Callback function on success |
|
995 * @param {function} errorCallback Callback function on failure |
|
996 * @param {object} options Object with properties .page and .limit for paging |
|
997 */ |
|
998 |
|
999 Contacts.prototype.find = function(filter, successCallback, errorCallback, options) { |
|
1000 try { |
|
1001 this.contactsService = device.getServiceObject("Service.Contact", "IDataSource"); |
|
1002 if (typeof options == 'object') |
|
1003 this.options = options; |
|
1004 else |
|
1005 this.options = {}; |
|
1006 |
|
1007 var criteria = new Object(); |
|
1008 criteria.Type = "Contact"; |
|
1009 if (filter && filter.name) { |
|
1010 var searchTerm = ''; |
|
1011 if (filter.name.givenName && filter.name.givenName.length > 0) { |
|
1012 searchTerm += filter.name.givenName; |
|
1013 } |
|
1014 if (filter.name.familyName && filter.name.familyName.length > 0) { |
|
1015 searchTerm += searchTerm.length > 0 ? ' ' + filter.name.familyName : filter.name.familyName; |
|
1016 } |
|
1017 if (!filter.name.familyName && !filter.name.givenName && filter.name.formatted) { |
|
1018 searchTerm = filter.name.formatted; |
|
1019 } |
|
1020 criteria.Filter = { SearchVal: searchTerm }; |
|
1021 } |
|
1022 |
|
1023 if (typeof(successCallback) != 'function') |
|
1024 successCallback = function(){}; |
|
1025 if (typeof(errorCallback) != 'function') |
|
1026 errorCallback = function(){}; |
|
1027 if (isNaN(this.options.limit)) |
|
1028 this.options.limit = 200; |
|
1029 if (isNaN(this.options.page)) |
|
1030 this.options.page = 1; |
|
1031 |
|
1032 //need a closure here to bind this method to this instance of the Contacts object |
|
1033 this.global_success = successCallback; |
|
1034 var obj = this; |
|
1035 |
|
1036 //WRT: result.ReturnValue is an iterator of contacts |
|
1037 this.contactsService.IDataSource.GetList(criteria, function(transId, eventCode, result){ |
|
1038 obj.success_callback(result.ReturnValue); |
|
1039 }); |
|
1040 } |
|
1041 catch (ex) { |
|
1042 alert(ex.name + ": " + ex.message); |
|
1043 errorCallback(ex); |
|
1044 } |
|
1045 }; |
|
1046 |
|
1047 Contacts.prototype.success_callback = function(contacts_iterator) { |
|
1048 try { |
|
1049 var gapContacts = new Array(); |
|
1050 if (contacts_iterator) { |
|
1051 contacts_iterator.reset(); |
|
1052 var contact; |
|
1053 var i = 0; |
|
1054 var end = this.options.page * this.options.limit; |
|
1055 var start = end - this.options.limit; |
|
1056 while ((contact = contacts_iterator.getNext()) != undefined && i < end) { |
|
1057 try { |
|
1058 if (i >= start) { |
|
1059 var gapContact = new Contact(); |
|
1060 gapContact.name.givenName = Contacts.GetValue(contact, "FirstName"); |
|
1061 gapContact.name.familyName = Contacts.GetValue(contact, "LastName"); |
|
1062 gapContact.name.formatted = gapContact.name.givenName + " " + gapContact.name.familyName; |
|
1063 gapContact.emails = Contacts.getEmailsList(contact); |
|
1064 gapContact.phones = Contacts.getPhonesList(contact); |
|
1065 gapContact.address = Contacts.getAddress(contact); |
|
1066 gapContact.id = Contacts.GetValue(contact, "id"); |
|
1067 gapContacts.push(gapContact); |
|
1068 } |
|
1069 i++; |
|
1070 } catch (e) { |
|
1071 alert("ContactsError (" + e.name + ": " + e.message + ")"); |
|
1072 } |
|
1073 } |
|
1074 } |
|
1075 this.contacts = gapContacts; |
|
1076 this.global_success(gapContacts); |
|
1077 } catch (ex) { alert(ex.name + ": " + ex.message); } |
|
1078 }; |
|
1079 |
|
1080 Contacts.getEmailsList = function(contact) { |
|
1081 var emails = new Array(); |
|
1082 try { |
|
1083 emails[0] = { type:"General", address: Contacts.GetValue(contact, "EmailGen") }; |
|
1084 emails[1] = { type:"Work", address: Contacts.GetValue(contact, "EmailWork") }; |
|
1085 emails[2] = { type:"Home", address: Contacts.GetValue(contact, "EmailHome") }; |
|
1086 } catch (e) { |
|
1087 emails = []; |
|
1088 } |
|
1089 return emails; |
|
1090 }; |
|
1091 |
|
1092 Contacts.getPhonesList = function(contact) { |
|
1093 var phones = new Array(); |
|
1094 try { |
|
1095 phones[0] = { type:"Mobile", number: Contacts.GetValue(contact, "MobilePhoneGen") }; |
|
1096 phones[1] = { type:"Home", number: Contacts.GetValue(contact, "LandPhoneGen") }; |
|
1097 phones[2] = { type:"Fax", number: Contacts.GetValue(contact, "FaxNumberGen") }; |
|
1098 phones[3] = { type:"Work", number: Contacts.GetValue(contact, "LandPhoneWork") }; |
|
1099 phones[4] = { type:"WorkMobile", number: Contacts.GetValue(contact, "MobilePhoneWork") }; |
|
1100 } catch (e) { |
|
1101 phones = []; |
|
1102 } |
|
1103 return phones; |
|
1104 }; |
|
1105 |
|
1106 Contacts.getAddress = function(contact) { |
|
1107 var address = ""; |
|
1108 try { |
|
1109 address = Contacts.GetValue(contact, "AddrLabelHome") + ", " + Contacts.GetValue(contact, "AddrStreetHome") + ", " + |
|
1110 Contacts.GetValue(contact, "AddrLocalHome") + ", " + Contacts.GetValue(contact, "AddrRegionHome") + ", " + |
|
1111 Contacts.GetValue(contact, "AddrPostCodeHome") + ", " + Contacts.GetValue(contact, "AddrCountryHome"); |
|
1112 } catch (e) { |
|
1113 address = ""; |
|
1114 } |
|
1115 return address; |
|
1116 }; |
|
1117 |
|
1118 Contacts.GetValue = function(contactObj, key) { |
|
1119 try { |
|
1120 return contactObj[key]["Value"]; |
|
1121 } catch (e) { |
|
1122 return ""; |
|
1123 } |
|
1124 }; |
|
1125 |
|
1126 if (typeof navigator.contacts == "undefined") navigator.contacts = new Contacts(); |
|
1127 /** |
|
1128 * This class provides access to the debugging console. |
|
1129 * @constructor |
|
1130 */ |
|
1131 function DebugConsole() { |
|
1132 } |
|
1133 |
|
1134 /** |
|
1135 * Print a normal log message to the console |
|
1136 * @param {Object|String} message Message or object to print to the console |
|
1137 */ |
|
1138 DebugConsole.prototype.log = function(message) { |
|
1139 |
|
1140 //This ends up in C:\jslog_widget.log on the device |
|
1141 console.log(message); |
|
1142 }; |
|
1143 |
|
1144 /** |
|
1145 * Print a warning message to the console |
|
1146 * @param {Object|String} message Message or object to print to the console |
|
1147 */ |
|
1148 DebugConsole.prototype.warn = function(message) { |
|
1149 console.log(message); |
|
1150 }; |
|
1151 |
|
1152 /** |
|
1153 * Print an error message to the console |
|
1154 * @param {Object|String} message Message or object to print to the console |
|
1155 */ |
|
1156 DebugConsole.prototype.error = function(message) { |
|
1157 console.log(message); |
|
1158 }; |
|
1159 |
|
1160 if (typeof window.debug == "undefined") window.debug = new DebugConsole(); |
|
1161 PhoneGap.ExtendWrtDeviceObj = function(){ |
|
1162 |
|
1163 if (!window.device) |
|
1164 window.device = {}; |
|
1165 navigator.device = window.device; |
|
1166 |
|
1167 try { |
|
1168 |
|
1169 if (window.menu) |
|
1170 window.menu.hideSoftkeys(); |
|
1171 |
|
1172 device.available = PhoneGap.available; |
|
1173 device.platform = null; |
|
1174 device.version = null; |
|
1175 device.name = null; |
|
1176 device.uuid = null; |
|
1177 |
|
1178 var so = device.getServiceObject("Service.SysInfo", "ISysInfo"); |
|
1179 var pf = PhoneGap.GetWrtPlatformVersion(so); |
|
1180 device.platform = pf.platform; |
|
1181 device.version = pf.version; |
|
1182 device.uuid = PhoneGap.GetWrtDeviceProperty(so, "IMEI"); |
|
1183 device.name = PhoneGap.GetWrtDeviceProperty(so, "PhoneModel"); |
|
1184 } |
|
1185 catch (e) { |
|
1186 device.available = false; |
|
1187 } |
|
1188 }; |
|
1189 |
|
1190 PhoneGap.GetWrtDeviceProperty = function(serviceObj, key) { |
|
1191 var criteria = { "Entity": "Device", "Key": key }; |
|
1192 var result = serviceObj.ISysInfo.GetInfo(criteria); |
|
1193 if (result.ErrorCode == 0) { |
|
1194 return result.ReturnValue.StringData; |
|
1195 } |
|
1196 else { |
|
1197 return null; |
|
1198 } |
|
1199 }; |
|
1200 |
|
1201 PhoneGap.GetWrtPlatformVersion = function(serviceObj) { |
|
1202 var criteria = { "Entity": "Device", "Key": "PlatformVersion" }; |
|
1203 var result = serviceObj.ISysInfo.GetInfo(criteria); |
|
1204 if (result.ErrorCode == 0) { |
|
1205 var version = {}; |
|
1206 version.platform = result.ReturnValue.MajorVersion; |
|
1207 version.version = result.ReturnValue.MinorVersion; |
|
1208 return version; |
|
1209 } |
|
1210 else { |
|
1211 return null; |
|
1212 } |
|
1213 }; |
|
1214 |
|
1215 PhoneGap.ExtendWrtDeviceObj();/** |
|
1216 * This class provides access to device GPS data. |
|
1217 * @constructor |
|
1218 */ |
|
1219 function Geolocation() { |
|
1220 /** |
|
1221 * The last known GPS position. |
|
1222 */ |
|
1223 this.lastPosition = null; |
|
1224 this.lastError = null; |
|
1225 this.callbacks = { |
|
1226 onLocationChanged: [], |
|
1227 onError: [] |
|
1228 }; |
|
1229 }; |
|
1230 |
|
1231 /** |
|
1232 * Asynchronously aquires the current position. |
|
1233 * @param {Function} successCallback The function to call when the position |
|
1234 * data is available |
|
1235 * @param {Function} errorCallback The function to call when there is an error |
|
1236 * getting the position data. |
|
1237 * @param {PositionOptions} options The options for getting the position data |
|
1238 * such as timeout. |
|
1239 */ |
|
1240 Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) { |
|
1241 var referenceTime = 0; |
|
1242 if (this.lastPosition) |
|
1243 referenceTime = this.lastPosition.timestamp; |
|
1244 else |
|
1245 this.start(options); |
|
1246 |
|
1247 var timeout = 20000; |
|
1248 var interval = 500; |
|
1249 if (typeof(options) == 'object' && options.interval) |
|
1250 interval = options.interval; |
|
1251 |
|
1252 if (typeof(successCallback) != 'function') |
|
1253 successCallback = function() {}; |
|
1254 if (typeof(errorCallback) != 'function') |
|
1255 errorCallback = function() {}; |
|
1256 |
|
1257 var dis = this; |
|
1258 var delay = 0; |
|
1259 var timer = setInterval(function() { |
|
1260 delay += interval; |
|
1261 //if we have a new position, call success and cancel the timer |
|
1262 if (dis.lastPosition && dis.lastPosition.timestamp > referenceTime) { |
|
1263 successCallback(dis.lastPosition); |
|
1264 clearInterval(timer); |
|
1265 } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer |
|
1266 errorCallback(); |
|
1267 clearInterval(timer); |
|
1268 } |
|
1269 //else the interval gets called again |
|
1270 }, interval); |
|
1271 }; |
|
1272 |
|
1273 /** |
|
1274 * Asynchronously aquires the position repeatedly at a given interval. |
|
1275 * @param {Function} successCallback The function to call each time the position |
|
1276 * data is available |
|
1277 * @param {Function} errorCallback The function to call when there is an error |
|
1278 * getting the position data. |
|
1279 * @param {PositionOptions} options The options for getting the position data |
|
1280 * such as timeout and the frequency of the watch. |
|
1281 */ |
|
1282 Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) { |
|
1283 // Invoke the appropriate callback with a new Position object every time the implementation |
|
1284 // determines that the position of the hosting device has changed. |
|
1285 this.getCurrentPosition(successCallback, errorCallback, options); |
|
1286 var frequency = 10000; |
|
1287 if (typeof options == 'object' && options.frequency) |
|
1288 frequency = options.frequency; |
|
1289 var that = this; |
|
1290 return setInterval(function() { |
|
1291 that.getCurrentPosition(successCallback, errorCallback, options); |
|
1292 }, frequency); |
|
1293 }; |
|
1294 |
|
1295 |
|
1296 /** |
|
1297 * Clears the specified position watch. |
|
1298 * @param {String} watchId The ID of the watch returned from #watchPosition. |
|
1299 */ |
|
1300 Geolocation.prototype.clearWatch = function(watchId) { |
|
1301 clearInterval(watchId); |
|
1302 }; |
|
1303 |
|
1304 Geolocation.prototype.start = function(options) { |
|
1305 var so = device.getServiceObject("Service.Location", "ILocation"); |
|
1306 |
|
1307 //construct the criteria for our location request |
|
1308 var updateOptions = new Object(); |
|
1309 // Specify that location information need not be guaranteed. This helps in |
|
1310 // that the widget doesn't need to wait for that information possibly indefinitely. |
|
1311 updateOptions.PartialUpdates = true; |
|
1312 |
|
1313 //default 15 seconds |
|
1314 if (typeof(options) == 'object' && options.timeout) |
|
1315 //options.timeout in in ms, updateOptions.UpdateTimeout in microsecs |
|
1316 updateOptions.UpdateTimeOut = options.timeout * 1000; |
|
1317 |
|
1318 //default 1 second |
|
1319 if (typeof(options) == 'object' && options.interval) |
|
1320 //options.timeout in in ms, updateOptions.UpdateTimeout in microsecs |
|
1321 updateOptions.UpdateInterval = options.interval * 1000; |
|
1322 |
|
1323 // Initialize the criteria for the GetLocation call |
|
1324 var trackCriteria = new Object(); |
|
1325 // could use "BasicLocationInformation" or "GenericLocationInfo" |
|
1326 trackCriteria.LocationInformationClass = "GenericLocationInfo"; |
|
1327 trackCriteria.Updateoptions = updateOptions; |
|
1328 |
|
1329 var dis = this; |
|
1330 so.ILocation.Trace(trackCriteria, function(transId, eventCode, result) { |
|
1331 var retVal = result.ReturnValue; |
|
1332 |
|
1333 if (result.ErrorCode != 0 || isNaN(retVal.Latitude)) |
|
1334 return; |
|
1335 |
|
1336 // heading options: retVal.TrueCourse, retVal.MagneticHeading, retVal.Heading, retVal.MagneticCourse |
|
1337 // but retVal.Heading was the only field being returned with data on the test device (Nokia 5800) |
|
1338 // WRT does not provide accuracy |
|
1339 var newCoords = new Coordinates(retVal.Latitude, retVal.Longitude, retVal.Altitude, null, retVal.Heading, retVal.HorizontalSpeed); |
|
1340 var positionObj = { coords: newCoords, timestamp: (new Date()).getTime() }; |
|
1341 |
|
1342 dis.lastPosition = positionObj; |
|
1343 }); |
|
1344 |
|
1345 }; |
|
1346 |
|
1347 |
|
1348 if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation(); |
|
1349 |
|
1350 /** |
|
1351 * This class provides access to native mapping applications on the device. |
|
1352 */ |
|
1353 function Map() { |
|
1354 |
|
1355 } |
|
1356 |
|
1357 /** |
|
1358 * Shows a native map on the device with pins at the given positions. |
|
1359 * @param {Array} positions |
|
1360 */ |
|
1361 Map.prototype.show = function(positions) { |
|
1362 |
|
1363 var err = "map api is unimplemented on symbian.wrt"; |
|
1364 debug.log(err); |
|
1365 return { name: "MapError", message: err }; |
|
1366 |
|
1367 }; |
|
1368 |
|
1369 if (typeof navigator.map == "undefined") navigator.map = new Map(); |
|
1370 function Network() { |
|
1371 /** |
|
1372 * The last known Network status. |
|
1373 */ |
|
1374 this.lastReachability = null; |
|
1375 }; |
|
1376 |
|
1377 Network.prototype.isReachable = function(hostName, successCallback, options) { |
|
1378 var req = new XMLHttpRequest(); |
|
1379 req.open('GET', hostName, true); |
|
1380 req.onreadystatechange = function (aEvt) { |
|
1381 if (req.readyState == 4) { |
|
1382 if(req.status == 200) |
|
1383 successCallback(NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK); |
|
1384 else |
|
1385 successCallback(NetworkStatus.NOT_REACHABLE); |
|
1386 } |
|
1387 }; |
|
1388 req.send(null); |
|
1389 |
|
1390 }; |
|
1391 |
|
1392 /** |
|
1393 * This class contains information about any NetworkStatus. |
|
1394 * @constructor |
|
1395 */ |
|
1396 function NetworkStatus() { |
|
1397 this.code = null; |
|
1398 this.message = ""; |
|
1399 } |
|
1400 |
|
1401 NetworkStatus.NOT_REACHABLE = 0; |
|
1402 NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1; |
|
1403 NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2; |
|
1404 |
|
1405 if (typeof navigator.network == "undefined") navigator.network = new Network(); |
|
1406 /** |
|
1407 * This class provides access to notifications on the device. |
|
1408 */ |
|
1409 function Notification() { |
|
1410 |
|
1411 } |
|
1412 |
|
1413 Notification.prototype.vibrate = function(mills) |
|
1414 { |
|
1415 |
|
1416 if (!Notification.getSysinfoObject()) |
|
1417 Notification.embedSysinfoObject(); |
|
1418 |
|
1419 this.sysinfo = Notification.getSysinfoObject(); |
|
1420 this.sysinfo.startvibra(mills, 100); |
|
1421 }; |
|
1422 |
|
1423 //TODO: this is not beeping |
|
1424 Notification.prototype.beep = function(count, volume) |
|
1425 { |
|
1426 if (!Notification.getSysinfoObject()) |
|
1427 Notification.embedSysinfoObject(); |
|
1428 |
|
1429 this.sysinfo = Notification.getSysinfoObject(); |
|
1430 this.sysinfo.beep(220,2000); |
|
1431 }; |
|
1432 |
|
1433 |
|
1434 /** |
|
1435 * Open a native alert dialog, with a customizable title and button text. |
|
1436 * @param {String} message Message to print in the body of the alert |
|
1437 * @param {String} [title="Alert"] Title of the alert dialog (default: Alert) |
|
1438 * @param {String} [buttonLabel="OK"] Label of the close button (default: OK) |
|
1439 */ |
|
1440 Notification.prototype.alert = function(message, title, buttonLabel) { |
|
1441 // Default is to use a browser alert; this will use "index.html" as the title though |
|
1442 alert(message); |
|
1443 }; |
|
1444 |
|
1445 /** |
|
1446 * Start spinning the activity indicator on the statusbar |
|
1447 */ |
|
1448 Notification.prototype.activityStart = function() { |
|
1449 }; |
|
1450 |
|
1451 /** |
|
1452 * Stop spinning the activity indicator on the statusbar, if it's currently spinning |
|
1453 */ |
|
1454 Notification.prototype.activityStop = function() { |
|
1455 }; |
|
1456 |
|
1457 /** |
|
1458 * Causes the device to blink a status LED. |
|
1459 * @param {Integer} count The number of blinks. |
|
1460 * @param {String} colour The colour of the light. |
|
1461 */ |
|
1462 Notification.prototype.blink = function(count, colour) { |
|
1463 |
|
1464 }; |
|
1465 |
|
1466 Notification.embedSysinfoObject = function() { |
|
1467 var el = document.createElement("embed"); |
|
1468 el.setAttribute("type", "application/x-systeminfo-widget"); |
|
1469 el.setAttribute("hidden", "yes"); |
|
1470 document.getElementsByTagName("body")[0].appendChild(el); |
|
1471 return; |
|
1472 }; |
|
1473 |
|
1474 Notification.getSysinfoObject = function() { |
|
1475 return document.embeds[0]; |
|
1476 }; |
|
1477 |
|
1478 if (typeof navigator.notification == "undefined") navigator.notification = new Notification(); |
|
1479 /** |
|
1480 * This class provides access to the device orientation. |
|
1481 * @constructor |
|
1482 */ |
|
1483 function Orientation() { |
|
1484 /** |
|
1485 * The current orientation, or null if the orientation hasn't changed yet. |
|
1486 */ |
|
1487 this.currentOrientation = null; |
|
1488 } |
|
1489 |
|
1490 /** |
|
1491 * Set the current orientation of the phone. This is called from the device automatically. |
|
1492 * |
|
1493 * When the orientation is changed, the DOMEvent \c orientationChanged is dispatched against |
|
1494 * the document element. The event has the property \c orientation which can be used to retrieve |
|
1495 * the device's current orientation, in addition to the \c Orientation.currentOrientation class property. |
|
1496 * |
|
1497 * @param {Number} orientation The orientation to be set |
|
1498 */ |
|
1499 Orientation.prototype.setOrientation = function(orientation) { |
|
1500 if (orientation == this.currentOrientation) |
|
1501 return; |
|
1502 var old = this.currentOrientation; |
|
1503 |
|
1504 this.currentOrientation = orientation; |
|
1505 var e = document.createEvent('Events'); |
|
1506 e.initEvent('orientationChanged', 'false', 'false'); |
|
1507 e.orientation = orientation; |
|
1508 e.oldOrientation = old; |
|
1509 document.dispatchEvent(e); |
|
1510 }; |
|
1511 |
|
1512 /** |
|
1513 * Asynchronously aquires the current orientation. |
|
1514 * @param {Function} successCallback The function to call when the orientation |
|
1515 * is known. |
|
1516 * @param {Function} errorCallback The function to call when there is an error |
|
1517 * getting the orientation. |
|
1518 */ |
|
1519 Orientation.prototype.getCurrentOrientation = function(successCallback, errorCallback) { |
|
1520 // If the orientation is available then call success |
|
1521 // If the orientation is not available then call error |
|
1522 try { |
|
1523 if (!this.serviceObj) |
|
1524 this.serviceObj = this.getServiceObj(); |
|
1525 |
|
1526 if (this.serviceObj == null) |
|
1527 errorCallback({ |
|
1528 name: "DeviceErr", |
|
1529 message: "Could not initialize service object" |
|
1530 }); |
|
1531 |
|
1532 //get the sensor channel |
|
1533 var SensorParams = { |
|
1534 SearchCriterion: "Orientation" |
|
1535 }; |
|
1536 var returnvalue = this.serviceObj.ISensor.FindSensorChannel(SensorParams); |
|
1537 |
|
1538 var error = returnvalue["ErrorCode"]; |
|
1539 var errmsg = returnvalue["ErrorMessage"]; |
|
1540 if (!(error == 0 || error == 1012)) { |
|
1541 var ex = { |
|
1542 name: "Unable to find Sensor Channel: " + error, |
|
1543 message: errmsg |
|
1544 }; |
|
1545 errorCallback(ex); |
|
1546 } |
|
1547 var channelInfoMap = returnvalue["ReturnValue"][0]; |
|
1548 var criteria = { |
|
1549 ChannelInfoMap: channelInfoMap, |
|
1550 ListeningType: "ChannelData" |
|
1551 }; |
|
1552 |
|
1553 if (typeof(successCallback) != 'function') |
|
1554 successCallback = function(){ |
|
1555 }; |
|
1556 if (typeof(errorCallback) != 'function') |
|
1557 errorCallback = function(){ |
|
1558 }; |
|
1559 |
|
1560 this.success_callback = successCallback; |
|
1561 this.error_callback = errorCallback; |
|
1562 |
|
1563 //create a closure to persist this instance of orientation object into the RegisterForNofication callback |
|
1564 var obj = this; |
|
1565 |
|
1566 // TODO: this call crashes WRT, but there is no other way to read the orientation sensor |
|
1567 // http://discussion.forum.nokia.com/forum/showthread.php?t=182151&highlight=memory+leak |
|
1568 this.serviceObj.ISensor.RegisterForNotification(criteria, function(transId, eventCode, result){ |
|
1569 var criteria = { |
|
1570 TransactionID: transId |
|
1571 }; |
|
1572 try { |
|
1573 //var orientation = result.ReturnValue.DeviceOrientation; |
|
1574 obj.serviceObj.ISensor.Cancel(criteria); |
|
1575 |
|
1576 var orientation = null; |
|
1577 switch (result.ReturnValue.DeviceOrientation) { |
|
1578 case "DisplayUpwards": orientation = DisplayOrientation.FACE_UP; break; |
|
1579 case "DisplayDownwards": orientation = DisplayOrientation.FACE_DOWN; break; |
|
1580 case "DisplayUp": orientation = DisplayOrientation.PORTRAIT; break; |
|
1581 case "DisplayDown": orientation = DisplayOrientation.REVERSE_PORTRAIT; break; |
|
1582 case "DisplayRightUp": orientation = DisplayOrientation.LANDSCAPE_RIGHT_UP; break; |
|
1583 case "DisplayLeftUp": orientation = DisplayOrientation.LANDSCAPE_LEFT_UP; break; |
|
1584 |
|
1585 } |
|
1586 |
|
1587 obj.setOrientation(orientation); |
|
1588 |
|
1589 obj.success_callback(orientation); |
|
1590 |
|
1591 } |
|
1592 catch (ex) { |
|
1593 obj.serviceObj.ISensor.Cancel(criteria); |
|
1594 obj.error_callback(ex); |
|
1595 } |
|
1596 |
|
1597 }); |
|
1598 } catch (ex) { |
|
1599 errorCallback({ name: "OrientationError", message: ex.name + ": " + ex.message }); |
|
1600 } |
|
1601 }; |
|
1602 |
|
1603 /** |
|
1604 * Asynchronously aquires the orientation repeatedly at a given interval. |
|
1605 * @param {Function} successCallback The function to call each time the orientation |
|
1606 * data is available. |
|
1607 * @param {Function} errorCallback The function to call when there is an error |
|
1608 * getting the orientation data. |
|
1609 */ |
|
1610 Orientation.prototype.watchOrientation = function(successCallback, errorCallback, options) { |
|
1611 // Invoke the appropriate callback with a new Position object every time the implementation |
|
1612 // determines that the position of the hosting device has changed. |
|
1613 this.getCurrentOrientation(successCallback, errorCallback); |
|
1614 var frequency = (options != undefined)? options.frequency : 1000; |
|
1615 return setInterval(function() { |
|
1616 navigator.orientation.getCurrentOrientation(successCallback, errorCallback); |
|
1617 }, frequency); |
|
1618 }; |
|
1619 |
|
1620 /** |
|
1621 * Clears the specified orientation watch. |
|
1622 * @param {String} watchId The ID of the watch returned from #watchOrientation. |
|
1623 */ |
|
1624 Orientation.prototype.clearWatch = function(watchId) { |
|
1625 clearInterval(watchId); |
|
1626 }; |
|
1627 |
|
1628 //gets the Acceleration Service Object from WRT |
|
1629 Orientation.prototype.getServiceObj = function() { |
|
1630 var so; |
|
1631 |
|
1632 try { |
|
1633 so = device.getServiceObject("Service.Sensor", "ISensor"); |
|
1634 } catch (ex) { |
|
1635 throw { |
|
1636 name: "DeviceError", |
|
1637 message: ex.name + ": " + ex.message |
|
1638 }; |
|
1639 } |
|
1640 return so; |
|
1641 }; |
|
1642 |
|
1643 |
|
1644 /** |
|
1645 * This class encapsulates the possible orientation values. |
|
1646 * @constructor |
|
1647 */ |
|
1648 function DisplayOrientation() { |
|
1649 this.code = null; |
|
1650 this.message = ""; |
|
1651 } |
|
1652 |
|
1653 DisplayOrientation.PORTRAIT = 0; |
|
1654 DisplayOrientation.REVERSE_PORTRAIT = 1; |
|
1655 DisplayOrientation.LANDSCAPE_LEFT_UP = 2; |
|
1656 DisplayOrientation.LANDSCAPE_RIGHT_UP = 3; |
|
1657 DisplayOrientation.FACE_UP = 4; |
|
1658 DisplayOrientation.FACE_DOWN = 5; |
|
1659 |
|
1660 if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation(); |
|
1661 /** |
|
1662 * This class contains position information. |
|
1663 * @param {Object} lat |
|
1664 * @param {Object} lng |
|
1665 * @param {Object} acc |
|
1666 * @param {Object} alt |
|
1667 * @param {Object} altacc |
|
1668 * @param {Object} head |
|
1669 * @param {Object} vel |
|
1670 * @constructor |
|
1671 */ |
|
1672 function Position(coords, timestamp) { |
|
1673 this.coords = coords; |
|
1674 this.timestamp = new Date().getTime(); |
|
1675 } |
|
1676 |
|
1677 function Coordinates(lat, lng, alt, acc, head, vel) { |
|
1678 /** |
|
1679 * The latitude of the position. |
|
1680 */ |
|
1681 this.latitude = lat; |
|
1682 /** |
|
1683 * The longitude of the position, |
|
1684 */ |
|
1685 this.longitude = lng; |
|
1686 /** |
|
1687 * The accuracy of the position. |
|
1688 */ |
|
1689 this.accuracy = acc; |
|
1690 /** |
|
1691 * The altitude of the position. |
|
1692 */ |
|
1693 this.altitude = alt; |
|
1694 /** |
|
1695 * The direction the device is moving at the position. |
|
1696 */ |
|
1697 this.heading = head; |
|
1698 /** |
|
1699 * The velocity with which the device is moving at the position. |
|
1700 */ |
|
1701 this.speed = vel; |
|
1702 } |
|
1703 |
|
1704 /** |
|
1705 * This class specifies the options for requesting position data. |
|
1706 * @constructor |
|
1707 */ |
|
1708 function PositionOptions() { |
|
1709 /** |
|
1710 * Specifies the desired position accuracy. |
|
1711 */ |
|
1712 this.enableHighAccuracy = true; |
|
1713 /** |
|
1714 * The timeout after which if position data cannot be obtained the errorCallback |
|
1715 * is called. |
|
1716 */ |
|
1717 this.timeout = 10000; |
|
1718 } |
|
1719 |
|
1720 /** |
|
1721 * This class contains information about any GSP errors. |
|
1722 * @constructor |
|
1723 */ |
|
1724 function PositionError() { |
|
1725 this.code = null; |
|
1726 this.message = ""; |
|
1727 } |
|
1728 |
|
1729 PositionError.UNKNOWN_ERROR = 0; |
|
1730 PositionError.PERMISSION_DENIED = 1; |
|
1731 PositionError.POSITION_UNAVAILABLE = 2; |
|
1732 PositionError.TIMEOUT = 3; |
|
1733 /** |
|
1734 * This class provides access to the device SMS functionality. |
|
1735 * @constructor |
|
1736 */ |
|
1737 function Sms() { |
|
1738 |
|
1739 } |
|
1740 |
|
1741 /** |
|
1742 * Sends an SMS message. |
|
1743 * @param {Integer} number The phone number to send the message to. |
|
1744 * @param {String} message The contents of the SMS message to send. |
|
1745 * @param {Function} successCallback The function to call when the SMS message is sent. |
|
1746 * @param {Function} errorCallback The function to call when there is an error sending the SMS message. |
|
1747 * @param {PositionOptions} options The options for accessing the GPS location such as timeout and accuracy. |
|
1748 */ |
|
1749 Sms.prototype.send = function(number, message, successCallback, errorCallback, options) { |
|
1750 try { |
|
1751 if (!this.serviceObj) |
|
1752 this.serviceObj = this.getServiceObj(); |
|
1753 |
|
1754 // Setup input params using dot syntax |
|
1755 var criteria = new Object(); |
|
1756 criteria.MessageType = 'SMS'; |
|
1757 criteria.To = number; |
|
1758 criteria.BodyText = message; |
|
1759 |
|
1760 var result = this.serviceObj.IMessaging.Send(criteria); |
|
1761 if (result.ErrorCode != 0 && result.ErrorCode != "0") |
|
1762 { |
|
1763 var exception = { name: "SMSError", message: result.ErrorMessage }; |
|
1764 throw exception; |
|
1765 } else { |
|
1766 successCallback.call(); |
|
1767 } |
|
1768 } |
|
1769 catch(ex) |
|
1770 { |
|
1771 errorCallback.call({ name: "SmsError", message: ex.name + ": " + ex.message }); |
|
1772 } |
|
1773 |
|
1774 }; |
|
1775 |
|
1776 |
|
1777 //gets the Sms Service Object from WRT |
|
1778 Sms.prototype.getServiceObj = function() { |
|
1779 var so; |
|
1780 |
|
1781 try { |
|
1782 so = device.getServiceObject("Service.Messaging", "IMessaging"); |
|
1783 } catch (ex) { |
|
1784 throw { |
|
1785 name: "SmsError", |
|
1786 message: "Failed to load sms service (" + ex.name + ": " + ex.message + ")" |
|
1787 }; |
|
1788 } |
|
1789 return so; |
|
1790 }; |
|
1791 |
|
1792 if (typeof navigator.sms == "undefined") navigator.sms = new Sms();/** |
|
1793 * @author ryan |
|
1794 */ |
|
1795 |
|
1796 function Storage() { |
|
1797 this.available = true; |
|
1798 this.serialized = null; |
|
1799 this.items = null; |
|
1800 |
|
1801 if (!window.widget) { |
|
1802 this.available = false; |
|
1803 return; |
|
1804 } |
|
1805 var pref = window.widget.preferenceForKey(Storage.PREFERENCE_KEY); |
|
1806 |
|
1807 //storage not yet created |
|
1808 if (pref == "undefined" || pref == undefined) { |
|
1809 this.length = 0; |
|
1810 this.serialized = "({})"; |
|
1811 this.items = {}; |
|
1812 window.widget.setPreferenceForKey(this.serialized, Storage.PREFERENCE_KEY); |
|
1813 } else { |
|
1814 this.serialized = pref;'({"store_test": { "key": "store_test", "data": "asdfasdfs" },})'; |
|
1815 this.items = eval(this.serialized); |
|
1816 } |
|
1817 } |
|
1818 |
|
1819 Storage.PREFERENCE_KEY = "phonegap_storage_pref_key"; |
|
1820 |
|
1821 Storage.prototype.index = function (key) { |
|
1822 |
|
1823 }; |
|
1824 |
|
1825 Storage.prototype.getItem = function (key) { |
|
1826 try { |
|
1827 return this.items[key].data; |
|
1828 } catch (ex) { |
|
1829 return null; |
|
1830 } |
|
1831 }; |
|
1832 |
|
1833 Storage.prototype.setItem = function (key, data) { |
|
1834 |
|
1835 this.items[key] = { |
|
1836 "key": key, |
|
1837 "data": data |
|
1838 }; |
|
1839 |
|
1840 this.serialize(); |
|
1841 }; |
|
1842 |
|
1843 Storage.prototype.removeItem = function (key) { |
|
1844 |
|
1845 if (this.items[key]) { |
|
1846 this.items[key] = undefined; |
|
1847 } |
|
1848 this.serialize(); |
|
1849 }; |
|
1850 |
|
1851 Storage.prototype.clear = function () { |
|
1852 this.serialized = "({})"; |
|
1853 this.items = {}; |
|
1854 this.serialize(); |
|
1855 }; |
|
1856 |
|
1857 Storage.prototype.serialize = function() { |
|
1858 var json = ""; |
|
1859 |
|
1860 for (key in this.items) { |
|
1861 var item = this.items[key]; |
|
1862 if (typeof item != "undefined") { |
|
1863 json += "\"" + item.key + "\": { \"key\": \"" + item.key + "\", \"data\": \"" + item.data + "\" }, "; |
|
1864 } |
|
1865 } |
|
1866 this.serialized = "({" + json + "})"; |
|
1867 |
|
1868 window.widget.setPreferenceForKey( this.serialized, Storage.PREFERENCE_KEY); |
|
1869 }; |
|
1870 |
|
1871 if (typeof navigator.storage == "undefined" ) navigator.storage = new Storage(); |
|
1872 /** |
|
1873 * This class provides access to the telephony features of the device. |
|
1874 * @constructor |
|
1875 */ |
|
1876 function Telephony() { |
|
1877 this.number = ""; |
|
1878 } |
|
1879 |
|
1880 /** |
|
1881 * Calls the specifed number. |
|
1882 * @param {Integer} number The number to be called. |
|
1883 */ |
|
1884 Telephony.prototype.send = function(number) { |
|
1885 widget.openURL('tel:+' + number); |
|
1886 }; |
|
1887 |
|
1888 if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony(); |