|
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 contacts_iterator.reset(); |
|
1051 var contact; |
|
1052 var i = 0; |
|
1053 var end = this.options.page * this.options.limit; |
|
1054 var start = end - this.options.limit; |
|
1055 while ((contact = contacts_iterator.getNext()) != undefined && i < end) { |
|
1056 try { |
|
1057 if (i >= start) { |
|
1058 var gapContact = new Contact(); |
|
1059 gapContact.name.givenName = Contacts.GetValue(contact, "FirstName"); |
|
1060 gapContact.name.familyName = Contacts.GetValue(contact, "LastName"); |
|
1061 gapContact.name.formatted = gapContact.name.givenName + " " + gapContact.name.familyName; |
|
1062 gapContact.emails = Contacts.getEmailsList(contact); |
|
1063 gapContact.phones = Contacts.getPhonesList(contact); |
|
1064 gapContact.address = Contacts.getAddress(contact); |
|
1065 gapContact.id = Contacts.GetValue(contact, "id"); |
|
1066 gapContacts.push(gapContact); |
|
1067 } |
|
1068 i++; |
|
1069 } catch (e) { |
|
1070 alert("ContactsError (" + e.name + ": " + e.message + ")"); |
|
1071 } |
|
1072 } |
|
1073 this.contacts = gapContacts; |
|
1074 this.global_success(gapContacts); |
|
1075 } catch (ex) { alert(ex.name + ": " + ex.message); } |
|
1076 }; |
|
1077 |
|
1078 Contacts.getEmailsList = function(contact) { |
|
1079 var emails = new Array(); |
|
1080 try { |
|
1081 emails[0] = { type:"General", address: Contacts.GetValue(contact, "EmailGen") }; |
|
1082 emails[1] = { type:"Work", address: Contacts.GetValue(contact, "EmailWork") }; |
|
1083 emails[2] = { type:"Home", address: Contacts.GetValue(contact, "EmailHome") }; |
|
1084 } catch (e) { |
|
1085 emails = []; |
|
1086 } |
|
1087 return emails; |
|
1088 }; |
|
1089 |
|
1090 Contacts.getPhonesList = function(contact) { |
|
1091 var phones = new Array(); |
|
1092 try { |
|
1093 phones[0] = { type:"Mobile", number: Contacts.GetValue(contact, "MobilePhoneGen") }; |
|
1094 phones[1] = { type:"Home", number: Contacts.GetValue(contact, "LandPhoneGen") }; |
|
1095 phones[2] = { type:"Fax", number: Contacts.GetValue(contact, "FaxNumberGen") }; |
|
1096 phones[3] = { type:"Work", number: Contacts.GetValue(contact, "LandPhoneWork") }; |
|
1097 phones[4] = { type:"WorkMobile", number: Contacts.GetValue(contact, "MobilePhoneWork") }; |
|
1098 } catch (e) { |
|
1099 phones = []; |
|
1100 } |
|
1101 return phones; |
|
1102 }; |
|
1103 |
|
1104 Contacts.getAddress = function(contact) { |
|
1105 var address = ""; |
|
1106 try { |
|
1107 address = Contacts.GetValue(contact, "AddrLabelHome") + ", " + Contacts.GetValue(contact, "AddrStreetHome") + ", " + |
|
1108 Contacts.GetValue(contact, "AddrLocalHome") + ", " + Contacts.GetValue(contact, "AddrRegionHome") + ", " + |
|
1109 Contacts.GetValue(contact, "AddrPostCodeHome") + ", " + Contacts.GetValue(contact, "AddrCountryHome"); |
|
1110 } catch (e) { |
|
1111 address = ""; |
|
1112 } |
|
1113 return address; |
|
1114 }; |
|
1115 |
|
1116 Contacts.GetValue = function(contactObj, key) { |
|
1117 try { |
|
1118 return contactObj[key]["Value"]; |
|
1119 } catch (e) { |
|
1120 return ""; |
|
1121 } |
|
1122 }; |
|
1123 |
|
1124 if (typeof navigator.contacts == "undefined") navigator.contacts = new Contacts(); |
|
1125 /** |
|
1126 * This class provides access to the debugging console. |
|
1127 * @constructor |
|
1128 */ |
|
1129 function DebugConsole() { |
|
1130 } |
|
1131 |
|
1132 /** |
|
1133 * Print a normal log message to the console |
|
1134 * @param {Object|String} message Message or object to print to the console |
|
1135 */ |
|
1136 DebugConsole.prototype.log = function(message) { |
|
1137 |
|
1138 //This ends up in C:\jslog_widget.log on the device |
|
1139 console.log(message); |
|
1140 }; |
|
1141 |
|
1142 /** |
|
1143 * Print a warning message to the console |
|
1144 * @param {Object|String} message Message or object to print to the console |
|
1145 */ |
|
1146 DebugConsole.prototype.warn = function(message) { |
|
1147 }; |
|
1148 |
|
1149 /** |
|
1150 * Print an error message to the console |
|
1151 * @param {Object|String} message Message or object to print to the console |
|
1152 */ |
|
1153 DebugConsole.prototype.error = function(message) { |
|
1154 }; |
|
1155 |
|
1156 if (typeof window.debug == "undefined") window.debug = new DebugConsole(); |
|
1157 PhoneGap.ExtendWrtDeviceObj = function(){ |
|
1158 |
|
1159 if (!window.device) |
|
1160 window.device = {}; |
|
1161 navigator.device = window.device; |
|
1162 |
|
1163 try { |
|
1164 |
|
1165 if (window.menu) |
|
1166 window.menu.hideSoftkeys(); |
|
1167 |
|
1168 device.available = PhoneGap.available; |
|
1169 device.platform = null; |
|
1170 device.version = null; |
|
1171 device.name = null; |
|
1172 device.uuid = null; |
|
1173 |
|
1174 var so = device.getServiceObject("Service.SysInfo", "ISysInfo"); |
|
1175 var pf = PhoneGap.GetWrtPlatformVersion(so); |
|
1176 device.platform = pf.platform; |
|
1177 device.version = pf.version; |
|
1178 device.uuid = PhoneGap.GetWrtDeviceProperty(so, "IMEI"); |
|
1179 device.name = PhoneGap.GetWrtDeviceProperty(so, "PhoneModel"); |
|
1180 } |
|
1181 catch (e) { |
|
1182 device.available = false; |
|
1183 } |
|
1184 }; |
|
1185 |
|
1186 PhoneGap.GetWrtDeviceProperty = function(serviceObj, key) { |
|
1187 var criteria = { "Entity": "Device", "Key": key }; |
|
1188 var result = serviceObj.ISysInfo.GetInfo(criteria); |
|
1189 if (result.ErrorCode == 0) { |
|
1190 return result.ReturnValue.StringData; |
|
1191 } |
|
1192 else { |
|
1193 return null; |
|
1194 } |
|
1195 }; |
|
1196 |
|
1197 PhoneGap.GetWrtPlatformVersion = function(serviceObj) { |
|
1198 var criteria = { "Entity": "Device", "Key": "PlatformVersion" }; |
|
1199 var result = serviceObj.ISysInfo.GetInfo(criteria); |
|
1200 if (result.ErrorCode == 0) { |
|
1201 var version = {}; |
|
1202 version.platform = result.ReturnValue.MajorVersion; |
|
1203 version.version = result.ReturnValue.MinorVersion; |
|
1204 return version; |
|
1205 } |
|
1206 else { |
|
1207 return null; |
|
1208 } |
|
1209 }; |
|
1210 |
|
1211 PhoneGap.ExtendWrtDeviceObj();/** |
|
1212 * This class provides access to device GPS data. |
|
1213 * @constructor |
|
1214 */ |
|
1215 function Geolocation() { |
|
1216 /** |
|
1217 * The last known GPS position. |
|
1218 */ |
|
1219 this.lastPosition = null; |
|
1220 this.lastError = null; |
|
1221 this.callbacks = { |
|
1222 onLocationChanged: [], |
|
1223 onError: [] |
|
1224 }; |
|
1225 }; |
|
1226 |
|
1227 /** |
|
1228 * Asynchronously aquires the current position. |
|
1229 * @param {Function} successCallback The function to call when the position |
|
1230 * data is available |
|
1231 * @param {Function} errorCallback The function to call when there is an error |
|
1232 * getting the position data. |
|
1233 * @param {PositionOptions} options The options for getting the position data |
|
1234 * such as timeout. |
|
1235 */ |
|
1236 Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) { |
|
1237 var referenceTime = 0; |
|
1238 if (this.lastPosition) |
|
1239 referenceTime = this.lastPosition.timestamp; |
|
1240 else |
|
1241 this.start(options); |
|
1242 |
|
1243 var timeout = 20000; |
|
1244 var interval = 500; |
|
1245 if (typeof(options) == 'object' && options.interval) |
|
1246 interval = options.interval; |
|
1247 |
|
1248 if (typeof(successCallback) != 'function') |
|
1249 successCallback = function() {}; |
|
1250 if (typeof(errorCallback) != 'function') |
|
1251 errorCallback = function() {}; |
|
1252 |
|
1253 var dis = this; |
|
1254 var delay = 0; |
|
1255 var timer = setInterval(function() { |
|
1256 delay += interval; |
|
1257 //if we have a new position, call success and cancel the timer |
|
1258 if (dis.lastPosition && dis.lastPosition.timestamp > referenceTime) { |
|
1259 successCallback(dis.lastPosition); |
|
1260 clearInterval(timer); |
|
1261 } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer |
|
1262 errorCallback(); |
|
1263 clearInterval(timer); |
|
1264 } |
|
1265 //else the interval gets called again |
|
1266 }, interval); |
|
1267 }; |
|
1268 |
|
1269 /** |
|
1270 * Asynchronously aquires the position repeatedly at a given interval. |
|
1271 * @param {Function} successCallback The function to call each time the position |
|
1272 * data is available |
|
1273 * @param {Function} errorCallback The function to call when there is an error |
|
1274 * getting the position data. |
|
1275 * @param {PositionOptions} options The options for getting the position data |
|
1276 * such as timeout and the frequency of the watch. |
|
1277 */ |
|
1278 Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) { |
|
1279 // Invoke the appropriate callback with a new Position object every time the implementation |
|
1280 // determines that the position of the hosting device has changed. |
|
1281 this.getCurrentPosition(successCallback, errorCallback, options); |
|
1282 var frequency = 10000; |
|
1283 if (typeof options == 'object' && options.frequency) |
|
1284 frequency = options.frequency; |
|
1285 var that = this; |
|
1286 return setInterval(function() { |
|
1287 that.getCurrentPosition(successCallback, errorCallback, options); |
|
1288 }, frequency); |
|
1289 }; |
|
1290 |
|
1291 |
|
1292 /** |
|
1293 * Clears the specified position watch. |
|
1294 * @param {String} watchId The ID of the watch returned from #watchPosition. |
|
1295 */ |
|
1296 Geolocation.prototype.clearWatch = function(watchId) { |
|
1297 clearInterval(watchId); |
|
1298 }; |
|
1299 |
|
1300 Geolocation.prototype.start = function(options) { |
|
1301 var so = device.getServiceObject("Service.Location", "ILocation"); |
|
1302 |
|
1303 //construct the criteria for our location request |
|
1304 var updateOptions = new Object(); |
|
1305 // Specify that location information need not be guaranteed. This helps in |
|
1306 // that the widget doesn't need to wait for that information possibly indefinitely. |
|
1307 updateOptions.PartialUpdates = true; |
|
1308 |
|
1309 //default 15 seconds |
|
1310 if (typeof(options) == 'object' && options.timeout) |
|
1311 //options.timeout in in ms, updateOptions.UpdateTimeout in microsecs |
|
1312 updateOptions.UpdateTimeOut = options.timeout * 1000; |
|
1313 |
|
1314 //default 1 second |
|
1315 if (typeof(options) == 'object' && options.interval) |
|
1316 //options.timeout in in ms, updateOptions.UpdateTimeout in microsecs |
|
1317 updateOptions.UpdateInterval = options.interval * 1000; |
|
1318 |
|
1319 // Initialize the criteria for the GetLocation call |
|
1320 var trackCriteria = new Object(); |
|
1321 // could use "BasicLocationInformation" or "GenericLocationInfo" |
|
1322 trackCriteria.LocationInformationClass = "GenericLocationInfo"; |
|
1323 trackCriteria.Updateoptions = updateOptions; |
|
1324 |
|
1325 var dis = this; |
|
1326 so.ILocation.Trace(trackCriteria, function(transId, eventCode, result) { |
|
1327 var retVal = result.ReturnValue; |
|
1328 |
|
1329 if (result.ErrorCode != 0 || isNaN(retVal.Latitude)) |
|
1330 return; |
|
1331 |
|
1332 // heading options: retVal.TrueCourse, retVal.MagneticHeading, retVal.Heading, retVal.MagneticCourse |
|
1333 // but retVal.Heading was the only field being returned with data on the test device (Nokia 5800) |
|
1334 // WRT does not provide accuracy |
|
1335 var newCoords = new Coordinates(retVal.Latitude, retVal.Longitude, retVal.Altitude, null, retVal.Heading, retVal.HorizontalSpeed); |
|
1336 var positionObj = { coords: newCoords, timestamp: (new Date()).getTime() }; |
|
1337 |
|
1338 dis.lastPosition = positionObj; |
|
1339 }); |
|
1340 |
|
1341 }; |
|
1342 |
|
1343 |
|
1344 if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation(); |
|
1345 |
|
1346 /** |
|
1347 * This class provides access to native mapping applications on the device. |
|
1348 */ |
|
1349 function Map() { |
|
1350 |
|
1351 } |
|
1352 |
|
1353 /** |
|
1354 * Shows a native map on the device with pins at the given positions. |
|
1355 * @param {Array} positions |
|
1356 */ |
|
1357 Map.prototype.show = function(positions) { |
|
1358 |
|
1359 var err = "map api is unimplemented on symbian.wrt"; |
|
1360 debug.log(err); |
|
1361 return { name: "MapError", message: err }; |
|
1362 |
|
1363 }; |
|
1364 |
|
1365 if (typeof navigator.map == "undefined") navigator.map = new Map(); |
|
1366 function Network() { |
|
1367 /** |
|
1368 * The last known Network status. |
|
1369 */ |
|
1370 this.lastReachability = null; |
|
1371 }; |
|
1372 |
|
1373 Network.prototype.isReachable = function(hostName, successCallback, options) { |
|
1374 var req = new XMLHttpRequest(); |
|
1375 req.open('GET', hostName, true); |
|
1376 req.onreadystatechange = function (aEvt) { |
|
1377 if (req.readyState == 4) { |
|
1378 if(req.status == 200) |
|
1379 successCallback(NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK); |
|
1380 else |
|
1381 successCallback(NetworkStatus.NOT_REACHABLE); |
|
1382 } |
|
1383 }; |
|
1384 req.send(null); |
|
1385 |
|
1386 }; |
|
1387 |
|
1388 /** |
|
1389 * This class contains information about any NetworkStatus. |
|
1390 * @constructor |
|
1391 */ |
|
1392 function NetworkStatus() { |
|
1393 this.code = null; |
|
1394 this.message = ""; |
|
1395 } |
|
1396 |
|
1397 NetworkStatus.NOT_REACHABLE = 0; |
|
1398 NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1; |
|
1399 NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2; |
|
1400 |
|
1401 if (typeof navigator.network == "undefined") navigator.network = new Network(); |
|
1402 /** |
|
1403 * This class provides access to notifications on the device. |
|
1404 */ |
|
1405 function Notification() { |
|
1406 |
|
1407 } |
|
1408 |
|
1409 Notification.prototype.vibrate = function(mills) |
|
1410 { |
|
1411 |
|
1412 if (!Notification.getSysinfoObject()) |
|
1413 Notification.embedSysinfoObject(); |
|
1414 |
|
1415 this.sysinfo = Notification.getSysinfoObject(); |
|
1416 this.sysinfo.startvibra(mills, 100); |
|
1417 }; |
|
1418 |
|
1419 //TODO: this is not beeping |
|
1420 Notification.prototype.beep = function(count, volume) |
|
1421 { |
|
1422 if (!Notification.getSysinfoObject()) |
|
1423 Notification.embedSysinfoObject(); |
|
1424 |
|
1425 this.sysinfo = Notification.getSysinfoObject(); |
|
1426 this.sysinfo.beep(220,2000); |
|
1427 }; |
|
1428 |
|
1429 |
|
1430 /** |
|
1431 * Open a native alert dialog, with a customizable title and button text. |
|
1432 * @param {String} message Message to print in the body of the alert |
|
1433 * @param {String} [title="Alert"] Title of the alert dialog (default: Alert) |
|
1434 * @param {String} [buttonLabel="OK"] Label of the close button (default: OK) |
|
1435 */ |
|
1436 Notification.prototype.alert = function(message, title, buttonLabel) { |
|
1437 // Default is to use a browser alert; this will use "index.html" as the title though |
|
1438 alert(message); |
|
1439 }; |
|
1440 |
|
1441 /** |
|
1442 * Start spinning the activity indicator on the statusbar |
|
1443 */ |
|
1444 Notification.prototype.activityStart = function() { |
|
1445 }; |
|
1446 |
|
1447 /** |
|
1448 * Stop spinning the activity indicator on the statusbar, if it's currently spinning |
|
1449 */ |
|
1450 Notification.prototype.activityStop = function() { |
|
1451 }; |
|
1452 |
|
1453 /** |
|
1454 * Causes the device to blink a status LED. |
|
1455 * @param {Integer} count The number of blinks. |
|
1456 * @param {String} colour The colour of the light. |
|
1457 */ |
|
1458 Notification.prototype.blink = function(count, colour) { |
|
1459 |
|
1460 }; |
|
1461 |
|
1462 Notification.embedSysinfoObject = function() { |
|
1463 var el = document.createElement("embed"); |
|
1464 el.setAttribute("type", "application/x-systeminfo-widget"); |
|
1465 el.setAttribute("hidden", "yes"); |
|
1466 document.getElementsByTagName("body")[0].appendChild(el); |
|
1467 return; |
|
1468 }; |
|
1469 |
|
1470 Notification.getSysinfoObject = function() { |
|
1471 return document.embeds[0]; |
|
1472 }; |
|
1473 |
|
1474 if (typeof navigator.notification == "undefined") navigator.notification = new Notification(); |
|
1475 /** |
|
1476 * This class provides access to the device orientation. |
|
1477 * @constructor |
|
1478 */ |
|
1479 function Orientation() { |
|
1480 /** |
|
1481 * The current orientation, or null if the orientation hasn't changed yet. |
|
1482 */ |
|
1483 this.currentOrientation = null; |
|
1484 } |
|
1485 |
|
1486 /** |
|
1487 * Set the current orientation of the phone. This is called from the device automatically. |
|
1488 * |
|
1489 * When the orientation is changed, the DOMEvent \c orientationChanged is dispatched against |
|
1490 * the document element. The event has the property \c orientation which can be used to retrieve |
|
1491 * the device's current orientation, in addition to the \c Orientation.currentOrientation class property. |
|
1492 * |
|
1493 * @param {Number} orientation The orientation to be set |
|
1494 */ |
|
1495 Orientation.prototype.setOrientation = function(orientation) { |
|
1496 if (orientation == this.currentOrientation) |
|
1497 return; |
|
1498 var old = this.currentOrientation; |
|
1499 |
|
1500 this.currentOrientation = orientation; |
|
1501 var e = document.createEvent('Events'); |
|
1502 e.initEvent('orientationChanged', 'false', 'false'); |
|
1503 e.orientation = orientation; |
|
1504 e.oldOrientation = old; |
|
1505 document.dispatchEvent(e); |
|
1506 }; |
|
1507 |
|
1508 /** |
|
1509 * Asynchronously aquires the current orientation. |
|
1510 * @param {Function} successCallback The function to call when the orientation |
|
1511 * is known. |
|
1512 * @param {Function} errorCallback The function to call when there is an error |
|
1513 * getting the orientation. |
|
1514 */ |
|
1515 Orientation.prototype.getCurrentOrientation = function(successCallback, errorCallback) { |
|
1516 // If the orientation is available then call success |
|
1517 // If the orientation is not available then call error |
|
1518 try { |
|
1519 if (!this.serviceObj) |
|
1520 this.serviceObj = this.getServiceObj(); |
|
1521 |
|
1522 if (this.serviceObj == null) |
|
1523 errorCallback({ |
|
1524 name: "DeviceErr", |
|
1525 message: "Could not initialize service object" |
|
1526 }); |
|
1527 |
|
1528 //get the sensor channel |
|
1529 var SensorParams = { |
|
1530 SearchCriterion: "Orientation" |
|
1531 }; |
|
1532 var returnvalue = this.serviceObj.ISensor.FindSensorChannel(SensorParams); |
|
1533 |
|
1534 var error = returnvalue["ErrorCode"]; |
|
1535 var errmsg = returnvalue["ErrorMessage"]; |
|
1536 if (!(error == 0 || error == 1012)) { |
|
1537 var ex = { |
|
1538 name: "Unable to find Sensor Channel: " + error, |
|
1539 message: errmsg |
|
1540 }; |
|
1541 errorCallback(ex); |
|
1542 } |
|
1543 var channelInfoMap = returnvalue["ReturnValue"][0]; |
|
1544 var criteria = { |
|
1545 ChannelInfoMap: channelInfoMap, |
|
1546 ListeningType: "ChannelData" |
|
1547 }; |
|
1548 |
|
1549 if (typeof(successCallback) != 'function') |
|
1550 successCallback = function(){ |
|
1551 }; |
|
1552 if (typeof(errorCallback) != 'function') |
|
1553 errorCallback = function(){ |
|
1554 }; |
|
1555 |
|
1556 this.success_callback = successCallback; |
|
1557 this.error_callback = errorCallback; |
|
1558 |
|
1559 //create a closure to persist this instance of orientation object into the RegisterForNofication callback |
|
1560 var obj = this; |
|
1561 |
|
1562 // TODO: this call crashes WRT, but there is no other way to read the orientation sensor |
|
1563 // http://discussion.forum.nokia.com/forum/showthread.php?t=182151&highlight=memory+leak |
|
1564 this.serviceObj.ISensor.RegisterForNotification(criteria, function(transId, eventCode, result){ |
|
1565 var criteria = { |
|
1566 TransactionID: transId |
|
1567 }; |
|
1568 try { |
|
1569 //var orientation = result.ReturnValue.DeviceOrientation; |
|
1570 obj.serviceObj.ISensor.Cancel(criteria); |
|
1571 |
|
1572 var orientation = null; |
|
1573 switch (result.ReturnValue.DeviceOrientation) { |
|
1574 case "DisplayUpwards": orientation = DisplayOrientation.FACE_UP; break; |
|
1575 case "DisplayDownwards": orientation = DisplayOrientation.FACE_DOWN; break; |
|
1576 case "DisplayUp": orientation = DisplayOrientation.PORTRAIT; break; |
|
1577 case "DisplayDown": orientation = DisplayOrientation.REVERSE_PORTRAIT; break; |
|
1578 case "DisplayRightUp": orientation = DisplayOrientation.LANDSCAPE_RIGHT_UP; break; |
|
1579 case "DisplayLeftUp": orientation = DisplayOrientation.LANDSCAPE_LEFT_UP; break; |
|
1580 |
|
1581 } |
|
1582 |
|
1583 obj.setOrientation(orientation); |
|
1584 |
|
1585 obj.success_callback(orientation); |
|
1586 |
|
1587 } |
|
1588 catch (ex) { |
|
1589 obj.serviceObj.ISensor.Cancel(criteria); |
|
1590 obj.error_callback(ex); |
|
1591 } |
|
1592 |
|
1593 }); |
|
1594 } catch (ex) { |
|
1595 errorCallback({ name: "OrientationError", message: ex.name + ": " + ex.message }); |
|
1596 } |
|
1597 }; |
|
1598 |
|
1599 /** |
|
1600 * Asynchronously aquires the orientation repeatedly at a given interval. |
|
1601 * @param {Function} successCallback The function to call each time the orientation |
|
1602 * data is available. |
|
1603 * @param {Function} errorCallback The function to call when there is an error |
|
1604 * getting the orientation data. |
|
1605 */ |
|
1606 Orientation.prototype.watchOrientation = function(successCallback, errorCallback, options) { |
|
1607 // Invoke the appropriate callback with a new Position object every time the implementation |
|
1608 // determines that the position of the hosting device has changed. |
|
1609 this.getCurrentOrientation(successCallback, errorCallback); |
|
1610 var frequency = (options != undefined)? options.frequency : 1000; |
|
1611 return setInterval(function() { |
|
1612 navigator.orientation.getCurrentOrientation(successCallback, errorCallback); |
|
1613 }, frequency); |
|
1614 }; |
|
1615 |
|
1616 /** |
|
1617 * Clears the specified orientation watch. |
|
1618 * @param {String} watchId The ID of the watch returned from #watchOrientation. |
|
1619 */ |
|
1620 Orientation.prototype.clearWatch = function(watchId) { |
|
1621 clearInterval(watchId); |
|
1622 }; |
|
1623 |
|
1624 //gets the Acceleration Service Object from WRT |
|
1625 Orientation.prototype.getServiceObj = function() { |
|
1626 var so; |
|
1627 |
|
1628 try { |
|
1629 so = device.getServiceObject("Service.Sensor", "ISensor"); |
|
1630 } catch (ex) { |
|
1631 throw { |
|
1632 name: "DeviceError", |
|
1633 message: ex.name + ": " + ex.message |
|
1634 }; |
|
1635 } |
|
1636 return so; |
|
1637 }; |
|
1638 |
|
1639 |
|
1640 /** |
|
1641 * This class encapsulates the possible orientation values. |
|
1642 * @constructor |
|
1643 */ |
|
1644 function DisplayOrientation() { |
|
1645 this.code = null; |
|
1646 this.message = ""; |
|
1647 } |
|
1648 |
|
1649 DisplayOrientation.PORTRAIT = 0; |
|
1650 DisplayOrientation.REVERSE_PORTRAIT = 1; |
|
1651 DisplayOrientation.LANDSCAPE_LEFT_UP = 2; |
|
1652 DisplayOrientation.LANDSCAPE_RIGHT_UP = 3; |
|
1653 DisplayOrientation.FACE_UP = 4; |
|
1654 DisplayOrientation.FACE_DOWN = 5; |
|
1655 |
|
1656 if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation(); |
|
1657 /** |
|
1658 * This class contains position information. |
|
1659 * @param {Object} lat |
|
1660 * @param {Object} lng |
|
1661 * @param {Object} acc |
|
1662 * @param {Object} alt |
|
1663 * @param {Object} altacc |
|
1664 * @param {Object} head |
|
1665 * @param {Object} vel |
|
1666 * @constructor |
|
1667 */ |
|
1668 function Position(coords, timestamp) { |
|
1669 this.coords = coords; |
|
1670 this.timestamp = new Date().getTime(); |
|
1671 } |
|
1672 |
|
1673 function Coordinates(lat, lng, alt, acc, head, vel) { |
|
1674 /** |
|
1675 * The latitude of the position. |
|
1676 */ |
|
1677 this.latitude = lat; |
|
1678 /** |
|
1679 * The longitude of the position, |
|
1680 */ |
|
1681 this.longitude = lng; |
|
1682 /** |
|
1683 * The accuracy of the position. |
|
1684 */ |
|
1685 this.accuracy = acc; |
|
1686 /** |
|
1687 * The altitude of the position. |
|
1688 */ |
|
1689 this.altitude = alt; |
|
1690 /** |
|
1691 * The direction the device is moving at the position. |
|
1692 */ |
|
1693 this.heading = head; |
|
1694 /** |
|
1695 * The velocity with which the device is moving at the position. |
|
1696 */ |
|
1697 this.speed = vel; |
|
1698 } |
|
1699 |
|
1700 /** |
|
1701 * This class specifies the options for requesting position data. |
|
1702 * @constructor |
|
1703 */ |
|
1704 function PositionOptions() { |
|
1705 /** |
|
1706 * Specifies the desired position accuracy. |
|
1707 */ |
|
1708 this.enableHighAccuracy = true; |
|
1709 /** |
|
1710 * The timeout after which if position data cannot be obtained the errorCallback |
|
1711 * is called. |
|
1712 */ |
|
1713 this.timeout = 10000; |
|
1714 } |
|
1715 |
|
1716 /** |
|
1717 * This class contains information about any GSP errors. |
|
1718 * @constructor |
|
1719 */ |
|
1720 function PositionError() { |
|
1721 this.code = null; |
|
1722 this.message = ""; |
|
1723 } |
|
1724 |
|
1725 PositionError.UNKNOWN_ERROR = 0; |
|
1726 PositionError.PERMISSION_DENIED = 1; |
|
1727 PositionError.POSITION_UNAVAILABLE = 2; |
|
1728 PositionError.TIMEOUT = 3; |
|
1729 /** |
|
1730 * This class provides access to the device SMS functionality. |
|
1731 * @constructor |
|
1732 */ |
|
1733 function Sms() { |
|
1734 |
|
1735 } |
|
1736 |
|
1737 /** |
|
1738 * Sends an SMS message. |
|
1739 * @param {Integer} number The phone number to send the message to. |
|
1740 * @param {String} message The contents of the SMS message to send. |
|
1741 * @param {Function} successCallback The function to call when the SMS message is sent. |
|
1742 * @param {Function} errorCallback The function to call when there is an error sending the SMS message. |
|
1743 * @param {PositionOptions} options The options for accessing the GPS location such as timeout and accuracy. |
|
1744 */ |
|
1745 Sms.prototype.send = function(number, message, successCallback, errorCallback, options) { |
|
1746 try { |
|
1747 if (!this.serviceObj) |
|
1748 this.serviceObj = this.getServiceObj(); |
|
1749 |
|
1750 // Setup input params using dot syntax |
|
1751 var criteria = new Object(); |
|
1752 criteria.MessageType = 'SMS'; |
|
1753 criteria.To = number; |
|
1754 criteria.BodyText = message; |
|
1755 |
|
1756 var result = this.serviceObj.IMessaging.Send(criteria); |
|
1757 if (result.ErrorCode != 0 && result.ErrorCode != "0") |
|
1758 { |
|
1759 var exception = { name: "SMSError", message: result.ErrorMessage }; |
|
1760 throw exception; |
|
1761 } else { |
|
1762 successCallback.call(); |
|
1763 } |
|
1764 } |
|
1765 catch(ex) |
|
1766 { |
|
1767 errorCallback.call({ name: "SmsError", message: ex.name + ": " + ex.message }); |
|
1768 } |
|
1769 |
|
1770 }; |
|
1771 |
|
1772 |
|
1773 //gets the Sms Service Object from WRT |
|
1774 Sms.prototype.getServiceObj = function() { |
|
1775 var so; |
|
1776 |
|
1777 try { |
|
1778 so = device.getServiceObject("Service.Messaging", "IMessaging"); |
|
1779 } catch (ex) { |
|
1780 throw { |
|
1781 name: "SmsError", |
|
1782 message: "Failed to load sms service (" + ex.name + ": " + ex.message + ")" |
|
1783 }; |
|
1784 } |
|
1785 return so; |
|
1786 }; |
|
1787 |
|
1788 if (typeof navigator.sms == "undefined") navigator.sms = new Sms();/** |
|
1789 * @author ryan |
|
1790 */ |
|
1791 |
|
1792 function Storage() { |
|
1793 this.available = true; |
|
1794 this.serialized = null; |
|
1795 this.items = null; |
|
1796 |
|
1797 if (!window.widget) { |
|
1798 this.available = false; |
|
1799 return; |
|
1800 } |
|
1801 var pref = window.widget.preferenceForKey(Storage.PREFERENCE_KEY); |
|
1802 |
|
1803 //storage not yet created |
|
1804 if (pref == "undefined" || pref == undefined) { |
|
1805 this.length = 0; |
|
1806 this.serialized = "({})"; |
|
1807 this.items = {}; |
|
1808 window.widget.setPreferenceForKey(this.serialized, Storage.PREFERENCE_KEY); |
|
1809 } else { |
|
1810 this.serialized = pref;'({"store_test": { "key": "store_test", "data": "asdfasdfs" },})'; |
|
1811 this.items = eval(this.serialized); |
|
1812 } |
|
1813 } |
|
1814 |
|
1815 Storage.PREFERENCE_KEY = "phonegap_storage_pref_key"; |
|
1816 |
|
1817 Storage.prototype.index = function (key) { |
|
1818 |
|
1819 }; |
|
1820 |
|
1821 Storage.prototype.getItem = function (key) { |
|
1822 try { |
|
1823 return this.items[key].data; |
|
1824 } catch (ex) { |
|
1825 return null; |
|
1826 } |
|
1827 }; |
|
1828 |
|
1829 Storage.prototype.setItem = function (key, data) { |
|
1830 |
|
1831 this.items[key] = { |
|
1832 "key": key, |
|
1833 "data": data |
|
1834 }; |
|
1835 |
|
1836 this.serialize(); |
|
1837 }; |
|
1838 |
|
1839 Storage.prototype.removeItem = function (key) { |
|
1840 |
|
1841 if (this.items[key]) { |
|
1842 this.items[key] = undefined; |
|
1843 } |
|
1844 this.serialize(); |
|
1845 }; |
|
1846 |
|
1847 Storage.prototype.clear = function () { |
|
1848 this.serialized = "({})"; |
|
1849 this.items = {}; |
|
1850 this.serialize(); |
|
1851 }; |
|
1852 |
|
1853 Storage.prototype.serialize = function() { |
|
1854 var json = ""; |
|
1855 |
|
1856 for (key in this.items) { |
|
1857 var item = this.items[key]; |
|
1858 if (typeof item != "undefined") { |
|
1859 json += "\"" + item.key + "\": { \"key\": \"" + item.key + "\", \"data\": \"" + item.data + "\" }, "; |
|
1860 } |
|
1861 } |
|
1862 this.serialized = "({" + json + "})"; |
|
1863 |
|
1864 window.widget.setPreferenceForKey( this.serialized, Storage.PREFERENCE_KEY); |
|
1865 }; |
|
1866 |
|
1867 if (typeof navigator.storage == "undefined" ) navigator.storage = new Storage(); |
|
1868 /** |
|
1869 * This class provides access to the telephony features of the device. |
|
1870 * @constructor |
|
1871 */ |
|
1872 function Telephony() { |
|
1873 this.number = ""; |
|
1874 } |
|
1875 |
|
1876 /** |
|
1877 * Calls the specifed number. |
|
1878 * @param {Integer} number The number to be called. |
|
1879 */ |
|
1880 Telephony.prototype.send = function(number) { |
|
1881 widget.openURL('tel:+' + number); |
|
1882 }; |
|
1883 |
|
1884 if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony(); |