diff --git a/framework/assets/js/accelerometer.js b/framework/assets/js/accelerometer.js old mode 100644 new mode 100755 index 5b0fdc96..e9a93cba --- a/framework/assets/js/accelerometer.js +++ b/framework/assets/js/accelerometer.js @@ -1,9 +1,43 @@ +com.phonegap.AccelListenerProxy = function() { + this.className = "com.phonegap.AccelListener"; +}; +com.phonegap.AccelListenerProxy.prototype.getStatus = function() { + return PhoneGap.exec(this.className, "getStatus", []); +}; +com.phonegap.AccelListenerProxy.prototype.getAcceleration = function() { + var r = PhoneGap.exec(this.className, "getAcceleration", []); + var a = new Acceleration(r.x,r.y,r.z); + return a; +}; +com.phonegap.AccelListenerProxy.prototype.getX = function() { + return PhoneGap.exec(this.className, "getX", []); +}; +com.phonegap.AccelListenerProxy.prototype.getY = function() { + return PhoneGap.exec(this.className, "getY", []); +}; +com.phonegap.AccelListenerProxy.prototype.getZ = function() { + return PhoneGap.exec(this.className, "getZ", []); +}; +com.phonegap.AccelListenerProxy.prototype.start = function() { + return PhoneGap.exec(this.className, "start", []); +}; +com.phonegap.AccelListenerProxy.prototype.stop = function() { + return PhoneGap.exec(this.className, "stop", []); +}; +com.phonegap.AccelListenerProxy.prototype.setTimeout = function(timeout) { + return PhoneGap.exec(this.className, "setTimeout", [timeout]); +}; +com.phonegap.AccelListenerProxy.prototype.getTimeout = function() { + return PhoneGap.exec(this.className, "getTimeout", []); +}; +com.phonegap.AccelListener = new com.phonegap.AccelListenerProxy(); + function Acceleration(x, y, z) { this.x = x; this.y = y; this.z = z; this.timestamp = new Date().getTime(); -} +}; /** * This class provides access to device accelerometer data. @@ -20,7 +54,7 @@ function Accelerometer() { * List of accelerometer watch timers */ this.timers = {}; -} +}; Accelerometer.STOPPED = 0; Accelerometer.STARTING = 1; @@ -50,13 +84,12 @@ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, error } // Get current acceleration status - var status = Accel.getStatus(); + var status = com.phonegap.AccelListener.getStatus(); // If running, then call successCallback if (status == Accelerometer.RUNNING) { try { - navigator.accelerometer.turnOffTimer = 0; - var accel = new Acceleration(Accel.getX(), Accel.getY(), Accel.getZ()); + var accel = com.phonegap.AccelListener.getAcceleration(); successCallback(accel); } catch (e) { console.log("Accelerometer Error in successCallback: " + e); @@ -65,18 +98,18 @@ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, error // If not running, then start it else { - Accel.start(); + com.phonegap.AccelListener.start(); // Wait until started var timer = setInterval(function() { - var status = Accel.getStatus(); + var status = com.phonegap.AccelListener.getStatus(); if (status != Accelerometer.STARTING) { clearInterval(timer); // If accelerometer is running if (status == Accelerometer.RUNNING) { try { - var accel = new Acceleration(Accel.getX(), Accel.getY(), Accel.getZ()); + var accel = com.phonegap.AccelListener.getAcceleration(); successCallback(accel); } catch (e) { console.log("Accelerometer Error in successCallback: " + e); @@ -97,7 +130,7 @@ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, error } }, 10); } -} +}; /** * Asynchronously aquires the acceleration repeatedly at a given interval. @@ -125,22 +158,22 @@ Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallb } // Make sure accelerometer timeout > frequency + 10 sec - var timeout = Accel.getTimeout(); + var timeout = com.phonegap.AccelListener.getTimeout(); if (timeout < (frequency + 10000)) { - Accel.setTimeout(frequency + 10000); // set to frequency + 10 sec + com.phonegap.AccelListener.setTimeout(frequency + 10000); // set to frequency + 10 sec } var id = PhoneGap.createUUID(); - Accel.start(); + com.phonegap.AccelListener.start(); // Start watch timer navigator.accelerometer.timers[id] = setInterval(function() { - var status = Accel.getStatus(); + var status = com.phonegap.AccelListener.getStatus(); // If accelerometer is running if (status == Accelerometer.RUNNING) { try { - var accel = new Acceleration(Accel.getX(), Accel.getY(), Accel.getZ()); + var accel = com.phonegap.AccelListener.getAcceleration(); successCallback(accel); } catch (e) { console.log("Accelerometer Error in successCallback: " + e); @@ -162,7 +195,7 @@ Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallb }, (frequency ? frequency : 1)); return id; -} +}; /** * Clears the specified accelerometer watch. @@ -176,7 +209,7 @@ Accelerometer.prototype.clearWatch = function(id) { clearInterval(navigator.accelerometer.timers[id]); delete navigator.accelerometer.timers[id]; } -} +}; PhoneGap.addConstructor(function() { if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer(); diff --git a/framework/assets/js/camera.js b/framework/assets/js/camera.js index 21383f02..ba3668ac 100644 --- a/framework/assets/js/camera.js +++ b/framework/assets/js/camera.js @@ -1,3 +1,14 @@ +com.phonegap.CameraLauncherProxy = function() { + this.className = "com.phonegap.CameraLauncher"; +}; +com.phonegap.CameraLauncherProxy.prototype.setBase64 = function(b) { + return PhoneGap.exec(this.className, "setBase64", [b]); +}; +com.phonegap.CameraLauncherProxy.prototype.takePicture = function(quality) { + return PhoneGap.exec(this.className, "takePicture", [quality]); +}; +com.phonegap.CameraLauncher = new com.phonegap.CameraLauncherProxy(); + /** * This class provides access to the device camera. * @@ -34,10 +45,10 @@ Camera.prototype.getPicture = function(successCallback, errorCallback, options) this.errorCallback = errorCallback; this.options = options; if (options.quality) { - GapCam.takePicture(options.quality); + com.phonegap.CameraLauncher.takePicture(options.quality); } else { - GapCam.takePicture(80); + com.phonegap.CameraLauncher.takePicture(80); } }; @@ -52,7 +63,6 @@ Camera.prototype.success = function(picture) { } }; - /** * Callback function from native code that is called when there is an error * capturing an image, or the capture is cancelled. diff --git a/framework/assets/js/compass.js b/framework/assets/js/compass.js index 82d3b8be..54aebdbf 100644 --- a/framework/assets/js/compass.js +++ b/framework/assets/js/compass.js @@ -1,3 +1,26 @@ +com.phonegap.CompassListenerProxy = function() { + this.className = "com.phonegap.CompassListener"; +}; +com.phonegap.CompassListenerProxy.prototype.start = function() { + return PhoneGap.exec(this.className, "start", []); +}; +com.phonegap.CompassListenerProxy.prototype.stop = function() { + return PhoneGap.exec(this.className, "stop", []); +}; +com.phonegap.CompassListenerProxy.prototype.getStatus = function() { + return PhoneGap.exec(this.className, "getStatus", []); +}; +com.phonegap.CompassListenerProxy.prototype.getHeading = function() { + return PhoneGap.exec(this.className, "getHeading", []); +}; +com.phonegap.CompassListenerProxy.prototype.setTimeout = function(timeout) { + return PhoneGap.exec(this.className, "setTimeout", [timeout]); +}; +com.phonegap.CompassListenerProxy.prototype.getTimeout = function() { + return PhoneGap.exec(this.className, "getTimeout", []); +}; +com.phonegap.CompassListener = new com.phonegap.CompassListenerProxy(); + /** * This class provides access to device Compass data. * @constructor @@ -42,12 +65,12 @@ Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, o } // Get current compass status - var status = CompassHook.getStatus(); + var status = com.phonegap.CompassListener.getStatus(); // If running, then call successCallback if (status == Compass.RUNNING) { try { - var heading = CompassHook.getHeading(); + var heading = com.phonegap.CompassListener.getHeading(); successCallback(heading); } catch (e) { console.log("Compass Error in successCallback: " + e); @@ -56,18 +79,18 @@ Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, o // If not running, then start it else { - CompassHook.start(); + com.phonegap.CompassListener.start(); // Wait until started var timer = setInterval(function() { - var status = CompassHook.getStatus(); + var status = com.phonegap.CompassListener.getStatus(); if (status != Compass.STARTING) { clearInterval(timer); // If compass is running if (status == Compass.RUNNING) { try { - var heading = CompassHook.getHeading(); + var heading = com.phonegap.CompassListener.getHeading(); successCallback(heading); } catch (e) { console.log("Compass Error in successCallback: " + e); @@ -88,7 +111,7 @@ Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, o } }, 10); } -} +}; /** * Asynchronously aquires the heading repeatedly at a given interval. @@ -116,22 +139,22 @@ Compass.prototype.watchHeading= function(successCallback, errorCallback, options } // Make sure compass timeout > frequency + 10 sec - var timeout = CompassHook.getTimeout(); + var timeout = com.phonegap.CompassListener.getTimeout(); if (timeout < (frequency + 10000)) { - CompassHook.setTimeout(frequency + 10000); // set to frequency + 10 sec + com.phonegap.CompassListener.setTimeout(frequency + 10000); // set to frequency + 10 sec } var id = PhoneGap.createUUID(); - CompassHook.start(); + com.phonegap.CompassListener.start(); // Start watch timer navigator.compass.timers[id] = setInterval(function() { - var status = CompassHook.getStatus(); + var status = com.phonegap.CompassListener.getStatus(); // If compass is running if (status == Compass.RUNNING) { try { - var heading = CompassHook.getHeading(); + var heading = com.phonegap.CompassListener.getHeading(); successCallback(heading); } catch (e) { console.log("Compass Error in successCallback: " + e); @@ -153,7 +176,7 @@ Compass.prototype.watchHeading= function(successCallback, errorCallback, options }, (frequency ? frequency : 1)); return id; -} +}; /** @@ -168,7 +191,7 @@ Compass.prototype.clearWatch = function(id) { clearInterval(navigator.compass.timers[id]); delete navigator.compass.timers[id]; } -} +}; PhoneGap.addConstructor(function() { if (typeof navigator.compass == "undefined") navigator.compass = new Compass(); diff --git a/framework/assets/js/contact.js b/framework/assets/js/contact.js index 30e26a6d..f178eb96 100644 --- a/framework/assets/js/contact.js +++ b/framework/assets/js/contact.js @@ -1,81 +1,82 @@ -var Contact = function(){ - this.name = new ContactName(); - this.emails = []; - this.phones = []; -} +com.phonegap.ContactManagerProxy = function() { + this.className = "com.phonegap.ContactManager"; +}; +com.phonegap.ContactManagerProxy.prototype.getContactsAndSendBack = function() { + return PhoneGap.exec(this.className, "getContactsAndSendBack", []); +}; +com.phonegap.ContactManagerProxy.prototype.search = function(name, npa, mail) { + return PhoneGap.exec(this.className, "search", [name, npa, mail]); +}; +com.phonegap.ContactManager = new com.phonegap.ContactManagerProxy(); -var ContactName = function() -{ - this.formatted = ""; - this.familyName = ""; - this.givenName = ""; - this.additionalNames = []; - this.prefixes = []; - this.suffixes = []; -} +var Contact = function() { + this.name = new ContactName(); + this.emails = []; + this.phones = []; +}; +var ContactName = function() { + this.formatted = ""; + this.familyName = ""; + this.givenName = ""; + this.additionalNames = []; + this.prefixes = []; + this.suffixes = []; +}; -var ContactEmail = function() -{ - this.types = []; - this.address = ""; -} +var ContactEmail = function() { + this.types = []; + this.address = ""; +}; -var ContactPhoneNumber = function() -{ - this.types = []; - this.number = ""; -} +var ContactPhoneNumber = function() { + this.types = []; + this.number = ""; +}; +var Contacts = function() { + this.records = []; +}; -var Contacts = function() -{ - this.records = []; -} +Contacts.prototype.find = function(obj, win, fail) { + if(obj.name != null) { + // Build up the search term that we'll use in SQL, based on the structure/contents of the contact object passed into find. + var searchTerm = ''; + if (obj.name.givenName && obj.name.givenName.length > 0) { + searchTerm = obj.name.givenName.split(' ').join('%'); + } + if (obj.name.familyName && obj.name.familyName.length > 0) { + searchTerm += obj.name.familyName.split(' ').join('%'); + } + if (!obj.name.familyName && !obj.name.givenName && obj.name.formatted) { + searchTerm = obj.name.formatted; + } + com.phonegap.ContactManager.search(searchTerm, "", ""); + } + this.win = win; + this.fail = fail; +}; -Contacts.prototype.find = function(obj, win, fail) -{ - if(obj.name != null) - { - // Build up the search term that we'll use in SQL, based on the structure/contents of the contact object passed into find. - var searchTerm = ''; - if (obj.name.givenName && obj.name.givenName.length > 0) { - searchTerm = obj.name.givenName.split(' ').join('%'); - } - if (obj.name.familyName && obj.name.familyName.length > 0) { - searchTerm += obj.name.familyName.split(' ').join('%'); - } - if (!obj.name.familyName && !obj.name.givenName && obj.name.formatted) { - searchTerm = obj.name.formatted; - } - ContactHook.search(searchTerm, "", ""); - } - this.win = win; - this.fail = fail; -} +Contacts.prototype.droidFoundContact = function(name, npa, email) { + var contact = new Contact(); + contact.name = new ContactName(); + contact.name.formatted = name; + contact.name.givenName = name; + var mail = new ContactEmail(); + mail.types.push("home"); + mail.address = email; + contact.emails.push(mail); + phone = new ContactPhoneNumber(); + phone.types.push("home"); + phone.number = npa; + contact.phones.push(phone); + this.records.push(contact); +}; -Contacts.prototype.droidFoundContact = function(name, npa, email) -{ - var contact = new Contact(); - contact.name = new ContactName(); - contact.name.formatted = name; - contact.name.givenName = name; - var mail = new ContactEmail(); - mail.types.push("home"); - mail.address = email; - contact.emails.push(mail); - phone = new ContactPhoneNumber(); - phone.types.push("home"); - phone.number = npa; - contact.phones.push(phone); - this.records.push(contact); -} - -Contacts.prototype.droidDone = function() -{ - this.win(this.records); -} +Contacts.prototype.droidDone = function() { + this.win(this.records); +}; PhoneGap.addConstructor(function() { - if(typeof navigator.contacts == "undefined") navigator.contacts = new Contacts(); + if(typeof navigator.contacts == "undefined") navigator.contacts = new Contacts(); }); diff --git a/framework/assets/js/crypto.js b/framework/assets/js/crypto.js index 2a4d1718..3218a0c5 100644 --- a/framework/assets/js/crypto.js +++ b/framework/assets/js/crypto.js @@ -1,33 +1,36 @@ -var Crypto = function() -{ -} +com.phonegap.CryptoHandlerProxy = function() { + this.className = "com.phonegap.CryptoHandler"; +}; +com.phonegap.CryptoHandlerProxy.prototype.encrypt = function(pass, text) { + return PhoneGap.exec(this.className, "encrypt", [pass, text]); +}; +com.phonegap.CryptoHandlerProxy.prototype.decrypt = function(pass, text) { + return PhoneGap.exec(this.className, "decrypt", [pass, text]); +}; +com.phonegap.CryptoHandler = new com.phonegap.CryptoHandlerProxy(); -Crypto.prototype.encrypt = function(seed, string, callback) -{ - GapCrypto.encrypt(seed, string); - this.encryptWin = callback; -} +var Crypto = function() { +}; -Crypto.prototype.decrypt = function(seed, string, callback) -{ - GapCrypto.decrypt(seed, string); - this.decryptWin = callback; -} +Crypto.prototype.encrypt = function(seed, string, callback) { + com.phonegap.CryptoHandler.encrypt(seed, string); + this.encryptWin = callback; +}; -Crypto.prototype.gotCryptedString = function(string) -{ - this.encryptWin(string); -} +Crypto.prototype.decrypt = function(seed, string, callback) { + com.phonegap.CryptoHandler.decrypt(seed, string); + this.decryptWin = callback; +}; -Crypto.prototype.getPlainString = function(string) -{ - this.decryptWin(string); -} +Crypto.prototype.gotCryptedString = function(string) { + this.encryptWin(string); +}; + +Crypto.prototype.getPlainString = function(string) { + this.decryptWin(string); +}; PhoneGap.addConstructor(function() { - if (typeof navigator.Crypto == "undefined") - { - navigator.Crypto = new Crypto(); - } + if (typeof navigator.Crypto == "undefined") navigator.Crypto = new Crypto(); }); diff --git a/framework/assets/js/media.js b/framework/assets/js/media.js index 2a1fc2fe..345f1bb2 100755 --- a/framework/assets/js/media.js +++ b/framework/assets/js/media.js @@ -1,8 +1,39 @@ +com.phonegap.AudioHandlerProxy = function() { + this.className = "com.phonegap.AudioHandler"; +}; +com.phonegap.AudioHandlerProxy.prototype.startRecordingAudio = function(id, file) { + return PhoneGap.exec(this.className, "startRecordingAudio", [id, file]); +}; +com.phonegap.AudioHandlerProxy.prototype.stopRecordingAudio = function(id) { + return PhoneGap.exec(this.className, "stopRecordingAudio", [id]); +}; +com.phonegap.AudioHandlerProxy.prototype.startPlayingAudio = function(id, file) { + return PhoneGap.exec(this.className, "startPlayingAudio", [id, file]); +}; +com.phonegap.AudioHandlerProxy.prototype.pausePlayingAudio = function(id) { + return PhoneGap.exec(this.className, "pausePlayingAudio", [id]); +}; +com.phonegap.AudioHandlerProxy.prototype.stopPlayingAudio = function(id) { + return PhoneGap.exec(this.className, "stopPlayingAudio", [id]); +}; +com.phonegap.AudioHandlerProxy.prototype.getCurrentPositionAudio = function(id) { + return PhoneGap.exec(this.className, "getCurrentPositionAudio", [id]); +}; +com.phonegap.AudioHandlerProxy.prototype.getDurationAudio = function(id, file) { + return PhoneGap.exec(this.className, "getDurationAudio", [id, file]); +}; +com.phonegap.AudioHandler = new com.phonegap.AudioHandlerProxy(); + /** * List of media objects. + * PRIVATE */ PhoneGap.mediaObjects = {}; +/** + * Object that receives native callbacks. + * PRIVATE + */ PhoneGap.Media = function() {}; /** @@ -52,13 +83,32 @@ PhoneGap.Media.onStatus = function(id, msg, value) { * * @param src The file name or url to play * @param successCallback The callback to be called when the file is done playing or recording. - * successCallback() + * successCallback() - OPTIONAL * @param errorCallback The callback to be called if there is an error. - * errorCallback(int errorCode) + * errorCallback(int errorCode) - OPTIONAL * @param statusCallback The callback to be called when media status has changed. - * statusCallback(int statusCode) + * statusCallback(int statusCode) - OPTIONAL */ Media = function(src, successCallback, errorCallback, statusCallback) { + + // successCallback optional + if (successCallback && (typeof successCallback != "function")) { + console.log("Media Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback != "function")) { + console.log("Media Error: errorCallback is not a function"); + return; + } + + // statusCallback optional + if (statusCallback && (typeof statusCallback != "function")) { + console.log("Media Error: statusCallback is not a function"); + return; + } + this.id = PhoneGap.createUUID(); PhoneGap.mediaObjects[this.id] = this; this.src = src; @@ -100,21 +150,21 @@ MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; * Start or resume playing audio file. */ Media.prototype.play = function() { - GapAudio.startPlayingAudio(this.id, this.src); + com.phonegap.AudioHandler.startPlayingAudio(this.id, this.src); }; /** * Stop playing audio file. */ Media.prototype.stop = function() { - GapAudio.stopPlayingAudio(this.id); + com.phonegap.AudioHandler.stopPlayingAudio(this.id); }; /** * Pause playing audio file. */ Media.prototype.pause = function() { - GapAudio.pausePlayingAudio(this.id); + com.phonegap.AudioHandler.pausePlayingAudio(this.id); }; /** @@ -133,20 +183,20 @@ Media.prototype.getDuration = function() { * @return */ Media.prototype.getCurrentPosition = function() { - return GapAudio.getCurrentPositionAudio(this.id); + return com.phonegap.AudioHandler.getCurrentPositionAudio(this.id); }; /** * Start recording audio file. */ Media.prototype.startRecord = function() { - GapAudio.startRecordingAudio(this.id, this.src); + com.phonegap.AudioHandler.startRecordingAudio(this.id, this.src); }; /** * Stop recording audio file. */ Media.prototype.stopRecord = function() { - GapAudio.stopRecordingAudio(this.id); + com.phonegap.AudioHandler.stopRecordingAudio(this.id); }; diff --git a/framework/assets/js/network.js b/framework/assets/js/network.js old mode 100644 new mode 100755 index 47d9e89f..7328b9b0 --- a/framework/assets/js/network.js +++ b/framework/assets/js/network.js @@ -1,14 +1,30 @@ +com.phonegap.NetworkManagerProxy = function() { + this.className = "com.phonegap.NetworkManager"; +}; +com.phonegap.NetworkManagerProxy.prototype.isAvailable = function() { + return PhoneGap.exec(this.className, "isAvailable", []); +}; +com.phonegap.NetworkManagerProxy.prototype.isWifiActive = function() { + return PhoneGap.exec(this.className, "isWifiActive", []); +}; +com.phonegap.NetworkManagerProxy.prototype.isReachable = function(uri) { + return PhoneGap.exec(this.className, "isReachable", [uri]); +}; +com.phonegap.NetworkManager = new com.phonegap.NetworkManagerProxy(); + /** * This class contains information about any NetworkStatus. * @constructor */ function NetworkStatus() { - this.code = null; - this.message = ""; -} + this.code = null; + this.message = ""; +}; + NetworkStatus.NOT_REACHABLE = 0; NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1; NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2; + /** * This class provides access to device Network data (reachability). * @constructor @@ -21,6 +37,7 @@ function Network() { */ this.lastReachability = null; }; + /** * Called by the geolocation framework when the reachability status has changed. * @param {Reachibility} reachability The current reachability status. @@ -28,27 +45,29 @@ function Network() { Network.prototype.updateReachability = function(reachability) { this.lastReachability = reachability; }; + /** * * @param {Object} uri * @param {Function} win * @param {Object} options (isIpAddress:boolean) */ -Network.prototype.isReachable = function(uri, win, options) -{ - var status = new NetworkStatus(); - if(NetworkManager.isReachable(uri)) - { - if (NetworkManager.isWifiActive()) { - status.code = NetworkStatus.REACHABLE_VIA_WIFI_NETWORK; - } else { - status.code = NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK; - } - } else { - status.code = NetworkStatus.NOT_REACHABLE; - } +Network.prototype.isReachable = function(uri, win, options) { + var status = new NetworkStatus(); + if(com.phonegap.NetworkManager.isReachable(uri)) { + if (com.phonegap.NetworkManager.isWifiActive()) { + status.code = NetworkStatus.REACHABLE_VIA_WIFI_NETWORK; + } + else { + status.code = NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK; + } + } + else { + status.code = NetworkStatus.NOT_REACHABLE; + } win(status); }; + PhoneGap.addConstructor(function() { if (typeof navigator.network == "undefined") navigator.network = new Network(); }); \ No newline at end of file diff --git a/framework/assets/js/phonegap.js.base b/framework/assets/js/phonegap.js.base index 3e8937e0..c42bd5ff 100755 --- a/framework/assets/js/phonegap.js.base +++ b/framework/assets/js/phonegap.js.base @@ -1,6 +1,10 @@ if (typeof(DeviceInfo) != 'object') DeviceInfo = {}; +var com = {}; + +com.phonegap = {}; + /** * This represents the PhoneGap API itself, and provides a global namespace for accessing * information about the state of PhoneGap. @@ -229,13 +233,46 @@ PhoneGap.callbacks = {}; * @param {String[]} [args] Zero or more arguments to pass to the method */ PhoneGap.exec = function(clazz, action, args) { - return CommandManager.exec(clazz, action, callbackId, JSON.stringify(args), false); + try { + var callbackId = 0; + var r = CommandManager.exec(clazz, action, callbackId, JSON.stringify(args), false); + eval("var v="+r+";"); + + // If status is OK, then return value back to caller + if (v.status == 0) { + return v.message; + } + + // If error, then display error + else { + console.log("Error: Status="+r.status+" Message="+v.message); + return null; + } + } catch (e) { + console.log("Error: "+e); + } }; PhoneGap.execAsync = function(success, fail, clazz, action, args) { - var callbackId = clazz + PhoneGap.callbackId++; - PhoneGap.callbacks[callbackId] = {success:success, fail:fail}; - return CommandManager.exec(clazz, action, callbackId, JSON.stringify(args), true); + try { + var callbackId = clazz + PhoneGap.callbackId++; + PhoneGap.callbacks[callbackId] = {success:success, fail:fail}; + var r = CommandManager.exec(clazz, action, callbackId, JSON.stringify(args), true); + eval("var v="+r+";"); + + // If status is OK, then return value back to caller + if (v.status == 0) { + return v.message; + } + + // If error, then display error + else { + console.log("Error: Status="+r.status+" Message="+v.message); + return null; + } + } catch (e) { + console.log("Error: "+e); + } }; PhoneGap.callbackSuccess = function(callbackId, args) { diff --git a/framework/assets/js/storage.js b/framework/assets/js/storage.js index 6b5fb305..7930f3cf 100644 --- a/framework/assets/js/storage.js +++ b/framework/assets/js/storage.js @@ -1,89 +1,85 @@ +com.phonegap.StorageProxy = function() { + this.className = "com.phonegap.Storage"; +}; +com.phonegap.StorageProxy.prototype.executeSql = function(query, params, id) { + return PhoneGap.exec(this.className, "executeSql", [query, params, id]); +}; +com.phonegap.StorageProxy.prototype.openDatabase = function(name, version, display_name, size) { + return PhoneGap.exec(this.className, "openDatabase", [name, version, display_name, size]); +}; +com.phonegap.Storage = new com.phonegap.StorageProxy(); + /* * This is purely for the Android 1.5/1.6 HTML 5 Storage - * I was hoping that Android 2.0 would deprecate this, but given the fact that + * I was hoping that Android 2.0 would deprecate this, but given the fact that * most manufacturers ship with Android 1.5 and do not do OTA Updates, this is required */ -var DroidDB = function() -{ - this.txQueue = []; -} +var DroidDB = function() { + this.txQueue = []; +}; -DroidDB.prototype.addResult = function(rawdata, tx_id) -{ - eval("var data = " + rawdata); - var tx = this.txQueue[tx_id]; - tx.resultSet.push(data); -} +DroidDB.prototype.addResult = function(rawdata, tx_id) { + eval("var data = " + rawdata); + var tx = this.txQueue[tx_id]; + tx.resultSet.push(data); +}; -DroidDB.prototype.completeQuery = function(tx_id) -{ - var tx = this.txQueue[tx_id]; - var r = new result(); - r.rows.resultSet = tx.resultSet; - r.rows.length = tx.resultSet.length; - tx.win(r); -} +DroidDB.prototype.completeQuery = function(tx_id) { + var tx = this.txQueue[tx_id]; + var r = new result(); + r.rows.resultSet = tx.resultSet; + r.rows.length = tx.resultSet.length; + tx.win(r); +}; -DroidDB.prototype.fail = function(reason, tx_id) -{ - var tx = this.txQueue[tx_id]; - tx.fail(reason); -} +DroidDB.prototype.fail = function(reason, tx_id) { + var tx = this.txQueue[tx_id]; + tx.fail(reason); +}; -var DatabaseShell = function() -{ - -} +var DatabaseShell = function() { +}; -DatabaseShell.prototype.transaction = function(process) -{ - tx = new Tx(); - process(tx); -} +DatabaseShell.prototype.transaction = function(process) { + tx = new Tx(); + process(tx); +}; -var Tx = function() -{ - droiddb.txQueue.push(this); - this.id = droiddb.txQueue.length - 1; - this.resultSet = []; -} +var Tx = function() { + droiddb.txQueue.push(this); + this.id = droiddb.txQueue.length - 1; + this.resultSet = []; +}; -Tx.prototype.executeSql = function(query, params, win, fail) -{ - droidStorage.executeSql(query, params, this.id); - tx.win = win; - tx.fail = fail; -} +Tx.prototype.executeSql = function(query, params, win, fail) { + com.phonegap.Storage.executeSql(query, params, this.id); + tx.win = win; + tx.fail = fail; +}; -var result = function() -{ - this.rows = new Rows(); -} +var result = function() { + this.rows = new Rows(); +}; -var Rows = function() -{ - this.resultSet = []; - this.length = 0; -} +var Rows = function() { + this.resultSet = []; + this.length = 0; +}; -Rows.prototype.item = function(row_id) -{ - return this.resultSet[id]; -} +Rows.prototype.item = function(row_id) { + return this.resultSet[id]; +}; -var dbSetup = function(name, version, display_name, size) -{ - droidStorage.openDatabase(name, version, display_name, size) +var dbSetup = function(name, version, display_name, size) { + com.phonegap.Storage.openDatabase(name, version, display_name, size) db_object = new DatabaseShell(); return db_object; -} +}; PhoneGap.addConstructor(function() { - if (typeof window.openDatabase == "undefined") - { - navigator.openDatabase = window.openDatabase = dbSetup; - window.droiddb = new DroidDB(); - } + if (typeof window.openDatabase == "undefined") { + navigator.openDatabase = window.openDatabase = dbSetup; + window.droiddb = new DroidDB(); + } }); - diff --git a/framework/src/com/phonegap/AccelListener.java b/framework/src/com/phonegap/AccelListener.java old mode 100644 new mode 100755 index e6f385d4..5a342447 --- a/framework/src/com/phonegap/AccelListener.java +++ b/framework/src/com/phonegap/AccelListener.java @@ -2,18 +2,27 @@ package com.phonegap; import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandManager; +import com.phonegap.api.CommandResult; + import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.content.Context; +import android.content.Intent; import android.webkit.WebView; /** * This class listens to the accelerometer sensor and stores the latest * acceleration values x,y,z. */ -public class AccelListener extends Module implements SensorEventListener{ +public class AccelListener implements SensorEventListener, Command{ public static int STOPPED = 0; public static int STARTING = 1; @@ -22,8 +31,8 @@ public class AccelListener extends Module implements SensorEventListener{ public float TIMEOUT = 30000; // Timeout in msec to shut off listener - WebView mAppView; // WebView object - DroidGap mCtx; // DroidGap object + WebView webView; // WebView object + DroidGap ctx; // DroidGap object float x,y,z; // most recent acceleration values long timeStamp; // time of most recent value @@ -35,22 +44,138 @@ public class AccelListener extends Module implements SensorEventListener{ /** * Create an accelerometer listener. - * - * @param ctx The Activity (DroidGap) object - * @param appView */ - public AccelListener(WebView appView, DroidGap ctx) { - super(appView, ctx); - this.mCtx = ctx; - this.mAppView = appView; - this.sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE); + public AccelListener() { this.x = 0; this.y = 0; this.z = 0; this.timeStamp = 0; this.status = AccelListener.STOPPED; + } + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE); + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("getStatus")) { + int i = this.getStatus(); + return new CommandResult(status, i); + } + else if (action.equals("start")) { + int i = this.start(); + return new CommandResult(status, i); + } + else if (action.equals("stop")) { + this.stop(); + return new CommandResult(status, 0); + } + else if (action.equals("getAcceleration")) { + JSONObject r = new JSONObject(); + r.put("x", this.x); + r.put("y", this.y); + r.put("z", this.z); + return new CommandResult(status, r); + } + else if (action.equals("getX")) { + float f = this.getX(); + return new CommandResult(status, f); + } + else if (action.equals("getY")) { + float f = this.getY(); + return new CommandResult(status, f); + } + else if (action.equals("getZ")) { + float f = this.getZ(); + return new CommandResult(status, f); + } + else if (action.equals("setTimeout")) { + try { + float timeout = Float.parseFloat(args.getString(0)); + this.setTimeout(timeout); + return new CommandResult(status, 0); + } catch (NumberFormatException e) { + status = CommandResult.Status.INVALID_ACTION; + e.printStackTrace(); + } catch (JSONException e) { + status = CommandResult.Status.JSON_EXCEPTION; + e.printStackTrace(); + } + } + else if (action.equals("getTimeout")) { + float f = this.getTimeout(); + return new CommandResult(status, f); + } + return new CommandResult(status, result); + } catch (JSONException e) { + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { } + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + + /** + * Called by AccelBroker when listener is to be shut down. + * Stop listener. + */ + public void onDestroy() { + this.stop(); + } + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + /** * Start listening for acceleration sensor. * @@ -91,16 +216,6 @@ public class AccelListener extends Module implements SensorEventListener{ } this.status = AccelListener.STOPPED; } - - /** - * Called by AccelBroker when listener is to be shut down. - * Stop listener. - */ - @Override - public void onDestroy() { - super.onDestroy(); - this.stop(); - } public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub diff --git a/framework/src/com/phonegap/AudioHandler.java b/framework/src/com/phonegap/AudioHandler.java index 81727fc8..5d5455be 100755 --- a/framework/src/com/phonegap/AudioHandler.java +++ b/framework/src/com/phonegap/AudioHandler.java @@ -3,7 +3,15 @@ package com.phonegap; import java.util.HashMap; import java.util.Map.Entry; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandManager; +import com.phonegap.api.CommandResult; + import android.content.Context; +import android.content.Intent; import android.media.AudioManager; import android.webkit.WebView; @@ -18,31 +26,98 @@ import android.webkit.WebView; * android_asset: file name must start with /android_asset/sound.mp3 * sdcard: file name is just sound.mp3 */ -public class AudioHandler extends Module { - +public class AudioHandler implements Command { + + WebView webView; // WebView object + DroidGap ctx; // DroidGap object + HashMap players; // Audio player object - WebView mAppView; // Webview object - DroidGap mCtx; // DroidGap object /** * Constructor. - * - * @param view - * @param ctx */ - public AudioHandler(WebView view, DroidGap ctx) { - super(view, ctx); - this.mAppView = view; - this.mCtx = ctx; + public AudioHandler() { this.players = new HashMap(); } + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("startRecordingAudio")) { + this.startRecordingAudio(args.getString(0), args.getString(1)); + } + else if (action.equals("stopRecordingAudio")) { + this.stopRecordingAudio(args.getString(0)); + } + else if (action.equals("startPlayingAudio")) { + this.startPlayingAudio(args.getString(0), args.getString(1)); + } + else if (action.equals("pausePlayingAudio")) { + this.pausePlayingAudio(args.getString(0)); + } + else if (action.equals("stopPlayingAudio")) { + this.stopPlayingAudio(args.getString(0)); + } + else if (action.equals("getCurrentPositionAudio")) { + long l = this.getCurrentPositionAudio(args.getString(0)); + return new CommandResult(status, l); + } + else if (action.equals("getDurationAudio")) { + long l = this.getDurationAudio(args.getString(0), args.getString(1)); + return new CommandResult(status, l); + } + return new CommandResult(status, result); + } catch (JSONException e) { + e.printStackTrace(); + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + /** * Stop all audio players and recorders. */ - @Override public void onDestroy() { - super.onDestroy(); java.util.Set> s = this.players.entrySet(); java.util.Iterator> it = s.iterator(); while(it.hasNext()) { @@ -52,7 +127,23 @@ public class AudioHandler extends Module { } this.players.clear(); } - + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + /** * Start recording and save the specified file. * @@ -166,7 +257,7 @@ public class AudioHandler extends Module { * @param output 1=earpiece, 2=speaker */ public void setAudioOutputDevice(int output) { - AudioManager audiMgr = (AudioManager) mCtx.getSystemService(Context.AUDIO_SERVICE); + AudioManager audiMgr = (AudioManager) this.ctx.getSystemService(Context.AUDIO_SERVICE); if (output == 2) { audiMgr.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_SPEAKER, AudioManager.ROUTE_ALL); } @@ -184,7 +275,7 @@ public class AudioHandler extends Module { * @return 1=earpiece, 2=speaker */ public int getAudioOutputDevice() { - AudioManager audiMgr = (AudioManager) mCtx.getSystemService(Context.AUDIO_SERVICE); + AudioManager audiMgr = (AudioManager) this.ctx.getSystemService(Context.AUDIO_SERVICE); if (audiMgr.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_EARPIECE) { return 1; } diff --git a/framework/src/com/phonegap/AudioPlayer.java b/framework/src/com/phonegap/AudioPlayer.java index 238b4994..ca696ce6 100755 --- a/framework/src/com/phonegap/AudioPlayer.java +++ b/framework/src/com/phonegap/AudioPlayer.java @@ -95,7 +95,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On public void startRecording(String file) { if (this.mPlayer != null) { System.out.println("AudioPlayer Error: Can't record in play mode."); - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_PLAY_MODE_SET+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_PLAY_MODE_SET+");"); } // Make sure we're not already recording @@ -110,18 +110,18 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.recorder.prepare(); this.recorder.start(); this.state = MEDIA_RUNNING; - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); return; } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_STARTING_RECORDING+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_STARTING_RECORDING+");"); } else { System.out.println("AudioPlayer Error: Already recording."); - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_ALREADY_RECORDING+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_ALREADY_RECORDING+");"); } } @@ -148,7 +148,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.recorder.stop(); // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); } this.moveFile(this.audioFile); } @@ -166,7 +166,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On public void startPlaying(String file) { if (this.recorder != null) { System.out.println("AudioPlayer Error: Can't play in record mode."); - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_RECORD_MODE_SET+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_RECORD_MODE_SET+");"); } // If this is a new request to play audio @@ -193,7 +193,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On else { if (file.startsWith("/android_asset/")) { String f = file.substring(15); - android.content.res.AssetFileDescriptor fd = this.handler.mCtx.getBaseContext().getAssets().openFd(f); + android.content.res.AssetFileDescriptor fd = this.handler.ctx.getBaseContext().getAssets().openFd(f); this.mPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); } else { @@ -208,11 +208,11 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.state = MEDIA_STARTING; // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); } catch (Exception e) { e.printStackTrace(); - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_STARTING_PLAYBACK+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_STARTING_PLAYBACK+");"); } } @@ -225,11 +225,11 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.state = MEDIA_RUNNING; // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); } else { System.out.println("AudioPlayer Error: startPlaying() called during invalid state: "+this.state); - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_RESUME_STATE+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_RESUME_STATE+");"); } } } @@ -245,11 +245,11 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.state = MEDIA_PAUSED; // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); } else { System.out.println("AudioPlayer Error: pausePlaying() called during invalid state: "+this.state); - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_PAUSE_STATE+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_PAUSE_STATE+");"); } } @@ -262,11 +262,11 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.mPlayer.stop(); // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); } else { System.out.println("AudioPlayer Error: stopPlaying() called during invalid state: "+this.state); - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_STOP_STATE+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+MEDIA_ERROR_STOP_STATE+");"); } } @@ -279,7 +279,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.state = MEDIA_STOPPED; // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); } /** @@ -362,7 +362,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.state = MEDIA_RUNNING; // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_STATE+", "+this.state+");"); } // Save off duration @@ -370,7 +370,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.prepareOnly = false; // Send status notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_DURATION+","+this.duration+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_DURATION+","+this.duration+");"); } @@ -390,7 +390,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On this.mPlayer.release(); // Send error notification to JavaScript - this.handler.mCtx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+arg1+");"); + this.handler.ctx.sendJavascript("PhoneGap.Media.onStatus('" + this.id + "', "+MEDIA_ERROR+", "+arg1+");"); return false; } } diff --git a/framework/src/com/phonegap/CameraLauncher.java b/framework/src/com/phonegap/CameraLauncher.java index 654a3062..ff760191 100755 --- a/framework/src/com/phonegap/CameraLauncher.java +++ b/framework/src/com/phonegap/CameraLauncher.java @@ -6,9 +6,16 @@ import java.io.IOException; import java.io.OutputStream; import org.apache.commons.codec.binary.Base64; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandManager; +import com.phonegap.api.CommandResult; import android.app.Activity; import android.content.ContentValues; +import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; @@ -21,22 +28,89 @@ import android.webkit.WebView; * and returns the captured image. When the camera view is closed, the screen displayed before * the camera view was shown is redisplayed. */ -public class CameraLauncher extends ActivityResultModule { - +public class CameraLauncher implements Command { + + WebView webView; // WebView object + DroidGap ctx; // DroidGap object + private int mQuality; // Compression quality hint (0-100: 0=low quality & high compression, 100=compress of max quality) private Uri imageUri; // Uri of captured image private boolean base64 = true; /** * Constructor. - * - * @param view - * @param gap */ - public CameraLauncher(WebView view, DroidGap gap) { - super(view, gap); + public CameraLauncher() { } + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("setBase64")) { + this.setBase64(args.getBoolean(0)); + } + else if (action.equals("takePicture")) { + this.takePicture(args.getInt(0)); + } + return new CommandResult(status, result); + } catch (JSONException e) { + e.printStackTrace(); + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + + /** + * Called by AccelBroker when listener is to be shut down. + * Stop listener. + */ + public void onDestroy() { + } + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + /** * Set the type of data to return. The data can either be returned * as a base64 string or a URI that points to the file. @@ -70,7 +144,7 @@ public class CameraLauncher extends ActivityResultModule { intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo)); this.imageUri = Uri.fromFile(photo); - this.startActivityForResult(intent); + this.ctx.startActivityForResult((Command) this, intent); } /** @@ -81,15 +155,13 @@ public class CameraLauncher extends ActivityResultModule { * @param resultCode The integer result code returned by the child activity through its setResult(). * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). */ - @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { - super.onActivityResult(requestCode, resultCode, intent); // If image available if (resultCode == Activity.RESULT_OK) { try { // Read in bitmap of captured image - Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.gap.getContentResolver(), imageUri); + Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getContentResolver(), imageUri); // If sending base64 image back if (this.base64) { @@ -104,11 +176,11 @@ public class CameraLauncher extends ActivityResultModule { values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); Uri uri = null; try { - uri = this.gap.getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); } catch (UnsupportedOperationException e) { System.out.println("Can't write to external media storage."); try { - uri = this.gap.getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values); + uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values); } catch (UnsupportedOperationException ex) { System.out.println("Can't write to internal media storage."); this.failPicture("Error capturing image - no media storage found."); @@ -117,12 +189,12 @@ public class CameraLauncher extends ActivityResultModule { } // Add compressed version of captured image to returned media store Uri - OutputStream os = this.gap.getContentResolver().openOutputStream(uri); + OutputStream os = this.ctx.getContentResolver().openOutputStream(uri); bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os); os.close(); // Send Uri back to JavaScript for viewing image - this.sendJavascript("navigator.camera.success('" + uri.toString() + "');"); + this.ctx.sendJavascript("navigator.camera.success('" + uri.toString() + "');"); } } catch (IOException e) { e.printStackTrace(); @@ -153,7 +225,7 @@ public class CameraLauncher extends ActivityResultModule { byte[] code = jpeg_data.toByteArray(); byte[] output = Base64.encodeBase64(code); String js_out = new String(output); - this.sendJavascript("navigator.camera.success('" + js_out + "');"); + this.ctx.sendJavascript("navigator.camera.success('" + js_out + "');"); } } catch(Exception e) { @@ -167,6 +239,6 @@ public class CameraLauncher extends ActivityResultModule { * @param err */ public void failPicture(String err) { - this.sendJavascript("navigator.camera.error('" + err + "');"); + this.ctx.sendJavascript("navigator.camera.error('" + err + "');"); } } diff --git a/framework/src/com/phonegap/CompassListener.java b/framework/src/com/phonegap/CompassListener.java old mode 100644 new mode 100755 index 3b9b4dfa..a7809c04 --- a/framework/src/com/phonegap/CompassListener.java +++ b/framework/src/com/phonegap/CompassListener.java @@ -2,27 +2,34 @@ package com.phonegap; import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandResult; + import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.content.Context; +import android.content.Intent; import android.webkit.WebView; /** * This class listens to the compass sensor and stores the latest heading value. */ -public class CompassListener extends Module implements SensorEventListener{ +public class CompassListener implements SensorEventListener, Command{ public static int STOPPED = 0; public static int STARTING = 1; public static int RUNNING = 2; public static int ERROR_FAILED_TO_START = 3; - public float TIMEOUT = 30000; // Timeout in msec to shut off listener + public long TIMEOUT = 30000; // Timeout in msec to shut off listener - WebView mAppView; // WebView object - DroidGap mCtx; // Activity (DroidGap) object + WebView webView; // WebView object + DroidGap ctx; // DroidGap object int status; // status of listener float heading; // most recent heading value @@ -34,19 +41,108 @@ public class CompassListener extends Module implements SensorEventListener{ /** * Constructor. - * - * @param appView - * @param ctx The Activity (DroidGap) object */ - public CompassListener(WebView appView, DroidGap ctx) { - super(appView, ctx); - this.mCtx = ctx; - this.mAppView = appView; - this.sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE); + public CompassListener() { this.timeStamp = 0; this.status = CompassListener.STOPPED; } - + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE); + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("start")) { + this.start(); + } + else if (action.equals("stop")) { + this.stop(); + } + else if (action.equals("getStatus")) { + int i = this.getStatus(); + return new CommandResult(status, i); + } + else if (action.equals("getHeading")) { + float f = this.getHeading(); + return new CommandResult(status, f); + } + else if (action.equals("setTimeout")) { + this.setTimeout(args.getLong(0)); + } + else if (action.equals("getTimeout")) { + long l = this.getTimeout(); + return new CommandResult(status, l); + } + return new CommandResult(status, result); + } catch (JSONException e) { + e.printStackTrace(); + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + + /** + * Called when listener is to be shut down and object is being destroyed. + */ + public void onDestroy() { + this.stop(); + } + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + /** * Start listening for compass sensor. * @@ -88,13 +184,6 @@ public class CompassListener extends Module implements SensorEventListener{ this.status = CompassListener.STOPPED; } - /** - * Called when listener is to be shut down and object is being destroyed. - */ - @Override - public void onDestroy() { - this.stop(); - } public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub @@ -145,7 +234,7 @@ public class CompassListener extends Module implements SensorEventListener{ * * @param timeout Timeout in msec. */ - public void setTimeout(float timeout) { + public void setTimeout(long timeout) { this.TIMEOUT = timeout; } @@ -154,7 +243,7 @@ public class CompassListener extends Module implements SensorEventListener{ * * @return timeout in msec */ - public float getTimeout() { + public long getTimeout() { return this.TIMEOUT; } } diff --git a/framework/src/com/phonegap/ContactManager.java b/framework/src/com/phonegap/ContactManager.java old mode 100644 new mode 100755 index fcbdab3c..0e24df3d --- a/framework/src/com/phonegap/ContactManager.java +++ b/framework/src/com/phonegap/ContactManager.java @@ -1,17 +1,22 @@ package com.phonegap; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandResult; + import android.provider.Contacts.ContactMethods; import android.provider.Contacts.People; import android.util.Log; import android.webkit.WebView; -import android.app.Activity; -import android.content.ContentResolver; +import android.content.Intent; import android.net.Uri; import android.database.Cursor; import android.database.sqlite.SQLiteException; @SuppressWarnings("deprecation") -public class ContactManager extends Module { +public class ContactManager implements Command { public class ContactTriplet { @@ -19,21 +24,100 @@ public class ContactManager extends Module { public String email = ""; public String phone = ""; } - + + WebView webView; // WebView object + DroidGap ctx; // DroidGap object + private static final String LOG_TAG = "Contact Query"; - DroidGap mApp; - WebView mView; Uri mPeople = android.provider.Contacts.People.CONTENT_URI; Uri mPhone = android.provider.Contacts.Phones.CONTENT_URI; Uri mEmail = android.provider.Contacts.ContactMethods.CONTENT_URI; - - public ContactManager(WebView view, DroidGap app) - { - super(view, app); - mApp = app; - mView = view; + + /** + * Constructor. + */ + public ContactManager() { } + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("getContactsAndSendBack")) { + this.getContactsAndSendBack(); + } + else if (action.equals("search")) { + this.search(args.getString(0), args.getString(1), args.getString(2)); + } + return new CommandResult(status, result); + } catch (JSONException e) { + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + + /** + * Called by AccelBroker when listener is to be shut down. + * Stop listener. + */ + public void onDestroy() { + } + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + // This is to add backwards compatibility to the OLD Contacts API\ public void getContactsAndSendBack() { @@ -45,7 +129,7 @@ public class ContactManager extends Module { }; try{ - Cursor myCursor = mApp.managedQuery(mPeople, projection, + Cursor myCursor = this.ctx.managedQuery(mPeople, projection, null, null , People.NAME + " ASC"); processResults(myCursor, true); } @@ -77,7 +161,7 @@ public class ContactManager extends Module { }; try{ - Cursor myCursor = mApp.managedQuery(mEmail, projection, + Cursor myCursor = this.ctx.managedQuery(mEmail, projection, "contact_methods." + ContactMethods.DATA + " = ?" + "AND contact_methods.kind = 1", variables , ContactMethods.DATA + " ASC"); getMethodData(myCursor); @@ -126,7 +210,7 @@ public class ContactManager extends Module { }; try{ - Cursor myCursor = mApp.managedQuery(mPeople, projection, + Cursor myCursor = this.ctx.managedQuery(mPeople, projection, conditions, variables , People.NAME + " ASC"); processResults(myCursor, false); } @@ -162,26 +246,26 @@ public class ContactManager extends Module { // Code for backwards compatibility with the OLD Contacts API if (all) { - mApp.sendJavascript("navigator.ContactManager.droidAddContact('" + name + "','" + phoneNumber + "','" + email +"');"); + this.ctx.sendJavascript("navigator.ContactManager.droidAddContact('" + name + "','" + phoneNumber + "','" + email +"');"); } else { - mApp.sendJavascript("navigator.contacts.droidFoundContact('" + name + "','" + phoneNumber + "','" + email +"');"); + this.ctx.sendJavascript("navigator.contacts.droidFoundContact('" + name + "','" + phoneNumber + "','" + email +"');"); } } while (cur.moveToNext()); if (all) { - mApp.sendJavascript("navigator.ContactManager.droidDone();"); + this.ctx.sendJavascript("navigator.ContactManager.droidDone();"); } else { - mApp.sendJavascript("navigator.contacts.droidDone();"); + this.ctx.sendJavascript("navigator.contacts.droidDone();"); } } else { if (all) { - mApp.sendJavascript("navigator.ContactManager.fail();"); + this.ctx.sendJavascript("navigator.ContactManager.fail();"); } else { - mApp.sendJavascript("navigator.contacts.fail('None found!');"); + this.ctx.sendJavascript("navigator.contacts.fail('None found!');"); } } } @@ -205,10 +289,10 @@ public class ContactManager extends Module { if(data != null) { data.email = email; - mApp.sendJavascript("navigator.Contacts.droidFoundContact('" + data.name + "','" + data.phone + "','" + data.email +"');"); + this.ctx.sendJavascript("navigator.Contacts.droidFoundContact('" + data.name + "','" + data.phone + "','" + data.email +"');"); } } while (cur.moveToNext()); - mApp.sendJavascript("navigator.contacts.droidDoneContacts();"); + this.ctx.sendJavascript("navigator.contacts.droidDoneContacts();"); } } @@ -226,7 +310,7 @@ public class ContactManager extends Module { }; try{ - Cursor myCursor = mApp.managedQuery(mPeople, projection, + Cursor myCursor = this.ctx.managedQuery(mPeople, projection, People.PRIMARY_EMAIL_ID + " = ?", variables , People.NAME + " ASC"); data = getTriplet(myCursor); } @@ -281,7 +365,7 @@ public class ContactManager extends Module { try { - Cursor myCursor = mApp.managedQuery(mEmail, projection, + Cursor myCursor = this.ctx.managedQuery(mEmail, projection, "contact_methods." + ContactMethods._ID + " = ?" + " AND contact_methods.kind = 1", variables , ContactMethods.DATA + " ASC"); email = getEmailColumnData(myCursor); } diff --git a/framework/src/com/phonegap/CryptoHandler.java b/framework/src/com/phonegap/CryptoHandler.java old mode 100644 new mode 100755 index 9d0d2579..f02a5ef7 --- a/framework/src/com/phonegap/CryptoHandler.java +++ b/framework/src/com/phonegap/CryptoHandler.java @@ -1,38 +1,120 @@ package com.phonegap; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandResult; + +import android.content.Intent; import android.webkit.WebView; -public class CryptoHandler extends Module { +public class CryptoHandler implements Command { - WebView mView; + WebView webView; // WebView object + DroidGap ctx; // DroidGap object - public CryptoHandler(WebView view, DroidGap gap) - { - super(view, gap); - mView = view; + /** + * Constructor. + */ + public CryptoHandler() { } - - public void encrypt(String pass, String text) - { + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("encrypt")) { + this.encrypt(args.getString(0), args.getString(1)); + } + else if (action.equals("decrypt")) { + this.decrypt(args.getString(0), args.getString(1)); + } + return new CommandResult(status, result); + } catch (JSONException e) { + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + + /** + * Called by AccelBroker when listener is to be shut down. + * Stop listener. + */ + public void onDestroy() { + } + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + + public void encrypt(String pass, String text) { try { String encrypted = SimpleCrypto.encrypt(pass,text); - mView.loadUrl("javascript:Crypto.gotCryptedString('" + text + "')"); + // TODO: Why not just return text now? + this.ctx.sendJavascript("Crypto.gotCryptedString('" + text + "')"); } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); } - } - public void decrypt(String pass, String text) - { + public void decrypt(String pass, String text) { try { String decrypted = SimpleCrypto.decrypt(pass,text); - mView.loadUrl("javascript:Crypto.gotPlainString('" + text + "')"); + this.ctx.sendJavascript("Crypto.gotPlainString('" + text + "')"); } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); } } - } diff --git a/framework/src/com/phonegap/DroidGap.java b/framework/src/com/phonegap/DroidGap.java index 1578952d..abc2b5a2 100755 --- a/framework/src/com/phonegap/DroidGap.java +++ b/framework/src/com/phonegap/DroidGap.java @@ -71,34 +71,31 @@ import android.widget.LinearLayout; * @Override * public void onCreate(Bundle savedInstanceState) { * super.onCreate(savedInstanceState); - * super.addModule("com.phonegap.examples.MyModule", "MyModule"); * super.loadUrl("file:///android_asset/www/index.html"); * } * } */ public class DroidGap extends Activity { - - private static final String LOG_TAG = "DroidGap"; + + private static final String LOG_TAG = "DroidGap"; protected WebView appView; // The webview for our app protected ImageView splashScreen; protected Boolean loadInWebView = false; - private LinearLayout root; - - private Device gap; - private BrowserKey mKey; + private LinearLayout root; + + private Device gap; + private FileUtils fs; + private BrowserKey mKey; public CallbackServer callbackServer; private CommandManager commandManager; - + private String url; // The initial URL for our app private String baseUrl; // The base of the initial URL for our app // Variables to manage ActivityResultCallbacks private int activityResultCallbackCounter = 1000; - private HashMap activityResultCallbacks = new HashMap(); - - // List of modules started and managed - private HashMapmodules = new HashMap(); + private HashMap activityResultCallbacks = new HashMap(); /** * Called when the activity is first created. @@ -177,9 +174,9 @@ public class DroidGap extends Activity { WebViewReflect.setGeolocationEnabled(settings, true); // Bind the appView object to the gap class methods bindBrowser(appView); - if (this.getModule("com.phonegap.Storage") != null) { - Storage cupcakeStorage = (Storage)this.getModule("com.phonegap.Storage"); - cupcakeStorage.setStorage(appPackage); + if (this.commandManager.getCommand("com.phonegap.Storage") != null) { + Storage cupcakeStorage = (Storage)this.commandManager.getCommand("com.phonegap.Storage"); + cupcakeStorage.setStorage(appPackage); } } @@ -201,14 +198,8 @@ public class DroidGap extends Activity { protected void onPause(){ super.onPause(); - // Forward to modules - java.util.Set> s = this.modules.entrySet(); - java.util.Iterator> it = s.iterator(); - while(it.hasNext()) { - Entry entry = it.next(); - Module module = entry.getValue(); - module.onPause(); - } + // Forward to commands + this.commandManager.onPause(); // Send pause event to JavaScript appView.loadUrl("javascript:try{PhoneGap.onPause.fire();}catch(e){};"); @@ -224,14 +215,8 @@ public class DroidGap extends Activity { protected void onResume(){ super.onResume(); - // Forward to modules - java.util.Set> s = this.modules.entrySet(); - java.util.Iterator> it = s.iterator(); - while(it.hasNext()) { - Entry entry = it.next(); - Module module = entry.getValue(); - module.onResume(); - } + // Forward to commands + this.commandManager.onResume(); // Send resume event to JavaScript appView.loadUrl("javascript:try{PhoneGap.onResume.fire();}catch(e){};"); @@ -255,18 +240,11 @@ public class DroidGap extends Activity { // Clean up objects if (mKey != null) { - } - // Clean up modules - java.util.Set> s = this.modules.entrySet(); - java.util.Iterator> it = s.iterator(); - while(it.hasNext()) { - Entry entry = it.next(); - Module module = entry.getValue(); - module.onDestroy(); - } - + // Forward to commands + this.commandManager.onDestroy(); + if (callbackServer != null) { callbackServer.destroy(); } @@ -276,72 +254,26 @@ public class DroidGap extends Activity { callbackServer = new CallbackServer(); commandManager = new CommandManager(appView, this); gap = new Device(appView, this); + fs = new FileUtils(appView, this); mKey = new BrowserKey(appView, this); // This creates the new javascript interfaces for PhoneGap appView.addJavascriptInterface(commandManager, "CommandManager"); appView.addJavascriptInterface(gap, "DroidGap"); - this.addModule("com.phonegap.AccelListener", "Accel"); - this.addModule("com.phonegap.CameraLauncher", "GapCam"); - this.addModule("com.phonegap.ContactManager", "ContactHook"); - this.addModule("com.phonegap.FileUtils", "FileUtil"); - this.addModule("com.phonegap.NetworkManager", "NetworkManager"); - this.addModule("com.phonegap.CompassListener", "CompassHook"); - this.addModule("com.phonegap.CryptoHandler", "GapCrypto"); - appView.addJavascriptInterface(mKey, "BackButton"); - this.addModule("com.phonegap.AudioHandler", "GapAudio"); + + appView.addJavascriptInterface(fs, "FileUtil"); + appView.addJavascriptInterface(mKey, "BackButton"); + appView.addJavascriptInterface(callbackServer, "CallbackServer"); appView.addJavascriptInterface(new SplashScreen(this), "SplashScreen"); - - if (android.os.Build.VERSION.RELEASE.startsWith("1.")) - { - this.addModule("com.phonegap.Storage", "droidStorage"); - this.addModule("com.phonegap.GeoBroker", "Geo"); - } - } - - @SuppressWarnings("unchecked") - /** - * Add module to be loaded and made available from JavaScript. - * - * @param className The class to load - * @param javascriptInterface Bind the object to Javascript so that the methods can be - * accessed from Javascript using this variable name. - */ - public Object addModule(String className, String javascriptInterface) { - System.out.println("DroidGap.addModule("+className+", "+javascriptInterface+")"); - try { - Class cl = Class.forName(className); - Class partypes[] = new Class[2]; - partypes[0] = android.webkit.WebView.class; - partypes[1] = com.phonegap.DroidGap.class; - java.lang.reflect.Constructor ct = cl.getConstructor(partypes); - Object arglist[] = new Object[2]; - arglist[0] = this.appView; - arglist[1] = this; - Module module = ct.newInstance(arglist); - this.modules.put(className, module); - if (javascriptInterface != null) { - this.appView.addJavascriptInterface(module, javascriptInterface); + + if (android.os.Build.VERSION.RELEASE.startsWith("1.")) + { + Log.d(LOG_TAG, "bindBrowser: Adding droidStorage"); //@ibm + this.commandManager.addCommand("com.phonegap.Storage"); + this.commandManager.addCommand("com.phonegap.GeoBroker"); + } - return module; - } - catch (Exception e) { - e.printStackTrace(); - System.out.println("Error adding module "+className+"."); - } - return null; - } - - /** - * Get the loaded module. - * - * @param className The class of the loaded module. - * @return - */ - public Object getModule(String className) { - Object module = this.modules.get(className); - return module; } /** @@ -664,7 +596,7 @@ public class DroidGap extends Activity { } /** - * Any calls to Activity.startActivityForResult must go through ActivityResultCallback, so + * Any calls to Activity.startActivityForResult must use method below, so * the result can be routed to them correctly. * * This is done to eliminate the need to modify DroidGap.java to receive activity results. @@ -676,27 +608,31 @@ public class DroidGap extends Activity { */ @Override public void startActivityForResult(Intent intent, int requestCode) throws RuntimeException { - if ((requestCode < 0) || this.activityResultCallbacks.containsKey(requestCode)) { - super.startActivityForResult(intent, requestCode); + System.out.println("startActivityForResult(intent,"+requestCode+")"); + if (requestCode == -1) { + super.startActivityForResult(intent, requestCode); } else { - throw new RuntimeException("PhoneGap Exception: Do not call startActivityForResult() directly. Implement ActivityResultCallback instead."); + throw new RuntimeException("PhoneGap Exception: Call startActivityForResult(Command, Intent) instead."); } } - + /** - * Add activity result callback to receive onActivityResult() callbacks. - * - * @param callback The callback class - * @return The request code to use for the callback + * Launch an activity for which you would like a result when it finished. When this activity exits, + * your onActivityResult() method will be called. + * + * @param command The command object + * @param intent The intent to start + * @return The request code to use for the callback */ - public int addActivityResult(ActivityResultModule callback) { + public int startActivityForResult(Command command, Intent intent) { int requestCode = this.activityResultCallbackCounter++; - this.activityResultCallbacks.put(requestCode, callback); + this.activityResultCallbacks.put(requestCode, command); + super.startActivityForResult(intent, requestCode); return requestCode; } - @Override + @Override /** * Called when an activity you launched exits, giving you the requestCode you started it with, * the resultCode it returned, and any additional data from it. @@ -709,9 +645,9 @@ public class DroidGap extends Activity { protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); - ActivityResultModule callback = this.activityResultCallbacks.get(requestCode); + Command callback = this.activityResultCallbacks.remove(requestCode); if (callback != null) { - callback.onActivityResult(requestCode, resultCode, intent); + callback.onActivityResult(requestCode, resultCode, intent); } } } diff --git a/framework/src/com/phonegap/FileUtils.java b/framework/src/com/phonegap/FileUtils.java index bc6b3920..3f54f9b6 100644 --- a/framework/src/com/phonegap/FileUtils.java +++ b/framework/src/com/phonegap/FileUtils.java @@ -4,7 +4,7 @@ import java.io.*; import android.webkit.WebView; -public class FileUtils extends Module { +public class FileUtils { WebView mView; @@ -13,7 +13,6 @@ public class FileUtils extends Module { public FileUtils(WebView view, DroidGap gap) { - super(view, gap); mView = view; } diff --git a/framework/src/com/phonegap/GeoBroker.java b/framework/src/com/phonegap/GeoBroker.java index 512fa0f1..af9b211a 100644 --- a/framework/src/com/phonegap/GeoBroker.java +++ b/framework/src/com/phonegap/GeoBroker.java @@ -2,8 +2,13 @@ package com.phonegap; import java.util.HashMap; -import android.content.Context; -import android.location.Location; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandResult; + +import android.content.Intent; import android.webkit.WebView; /* @@ -12,38 +17,121 @@ import android.webkit.WebView; * This class only starts and stops various GeoListeners, which consist of a GPS and a Network Listener */ -public class GeoBroker extends Module { - private WebView mAppView; - private DroidGap mCtx; - private HashMap geoListeners; +public class GeoBroker implements Command { + + WebView webView; // WebView object + DroidGap ctx; // DroidGap object + + private HashMap geoListeners; private GeoListener global; - public GeoBroker(WebView view, DroidGap ctx) - { - super(view, ctx); - mCtx = ctx; - mAppView = view; - geoListeners = new HashMap(); + /** + * Constructor. + */ + public GeoBroker() { + this.geoListeners = new HashMap(); } - - public void getCurrentLocation() - { + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("getCurrentLocation")) { + this.getCurrentLocation(); + } + else if (action.equals("start")) { + String s = this.start(args.getInt(0), args.getString(1)); + return new CommandResult(status, s); + } + else if (action.equals("stop")) { + this.stop(args.getString(0)); + } + return new CommandResult(status, result); + } catch (JSONException e) { + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + + /** + * Called by AccelBroker when listener is to be shut down. + * Stop listener. + */ + public void onDestroy() { + } + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + + public void getCurrentLocation() { //It's supposed to run async! - if(global == null) - global = new GeoListener("global", mCtx, 10000, mAppView); - else + if (global == null) { + global = new GeoListener("global", this.ctx, 10000, this.webView); + } + else { global.start(10000); + } } - public String start(int freq, String key) - { - GeoListener listener = new GeoListener(key, mCtx, freq, mAppView); + public String start(int freq, String key) { + GeoListener listener = new GeoListener(key, this.ctx, freq, this.webView); geoListeners.put(key, listener); return key; } - public void stop(String key) - { + public void stop(String key) { GeoListener geo = geoListeners.get(key); } } diff --git a/framework/src/com/phonegap/NetworkManager.java b/framework/src/com/phonegap/NetworkManager.java index c13df3ac..bb9fb0f4 100644 --- a/framework/src/com/phonegap/NetworkManager.java +++ b/framework/src/com/phonegap/NetworkManager.java @@ -2,49 +2,137 @@ package com.phonegap; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandResult; import android.content.Context; +import android.content.Intent; import android.net.*; import android.webkit.WebView; -public class NetworkManager extends Module { +public class NetworkManager implements Command { - DroidGap mCtx; - WebView mView; - ConnectivityManager sockMan; + WebView webView; // WebView object + DroidGap ctx; // DroidGap object - public NetworkManager(WebView view, DroidGap ctx) - { - super(view, ctx); - mCtx = ctx; - mView = view; - sockMan = (ConnectivityManager) mCtx.getSystemService(Context.CONNECTIVITY_SERVICE); + ConnectivityManager sockMan; + + /** + * Constructor. + */ + public NetworkManager() { } - - public boolean isAvailable() - { + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + this.sockMan = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE); + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + try { + if (action.equals("isAvailable")) { + boolean b = this.isAvailable(); + return new CommandResult(status, b); + } + else if (action.equals("isWifiActive")) { + boolean b = this.isWifiActive(); + return new CommandResult(status, b); + } + else if (action.equals("isReachable")) { + boolean b = this.isReachable(args.getString(0)); + return new CommandResult(status, b); + } + return new CommandResult(status, result); + } catch (JSONException e) { + return new CommandResult(CommandResult.Status.JSON_EXCEPTION); + } + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + } + + /** + * Called by AccelBroker when listener is to be shut down. + * Stop listener. + */ + public void onDestroy() { + } + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + + public boolean isAvailable() { NetworkInfo info = sockMan.getActiveNetworkInfo(); boolean conn = false; - if(info != null) + if (info != null) { conn = info.isConnected(); + } return conn; } - public boolean isWifiActive() - { + public boolean isWifiActive() { NetworkInfo info = sockMan.getActiveNetworkInfo(); - if(info != null) - { + if (info != null) { String type = info.getTypeName(); return type.equals("WIFI"); } return false; } - public boolean isReachable(String uri) - { - if (uri.indexOf("http://") == -1) + public boolean isReachable(String uri) { + if (uri.indexOf("http://") == -1) { uri = "http://" + uri; + } boolean reached = isAvailable(); try { DefaultHttpClient httpclient = new DefaultHttpClient(); diff --git a/framework/src/com/phonegap/Storage.java b/framework/src/com/phonegap/Storage.java index 9b010d53..4606dc22 100644 --- a/framework/src/com/phonegap/Storage.java +++ b/framework/src/com/phonegap/Storage.java @@ -1,25 +1,122 @@ package com.phonegap; +import org.json.JSONArray; +import org.json.JSONException; + +import com.phonegap.api.Command; +import com.phonegap.api.CommandResult; + +import android.content.Intent; import android.database.Cursor; import android.database.sqlite.*; import android.util.Log; import android.webkit.WebView; -public class Storage extends Module { +public class Storage implements Command { private static final String LOG_TAG = "SQLite Storage:"; + + WebView webView; // WebView object + DroidGap ctx; // DroidGap object + SQLiteDatabase myDb; String path; String txid = ""; - WebView appView; - DroidGap mCtx; - public Storage(WebView view, DroidGap ctx) { - super(view, ctx); - appView = view; - mCtx = ctx; + /** + * Constructor. + */ + public Storage() { } + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param ctx The context of the main Activity. + */ + public void setContext(DroidGap ctx) { + this.ctx = ctx; + } + + /** + * Sets the main View of the application, this is the WebView within which + * a PhoneGap app runs. + * + * @param webView The PhoneGap WebView + */ + public void setView(WebView webView) { + this.webView = webView; + } + + /** + * Executes the request and returns CommandResult. + * + * @param action The command to execute. + * @param args JSONArry of arguments for the command. + * @return A CommandResult object with a status and message. + */ + public CommandResult execute(String action, JSONArray args) { + CommandResult.Status status = CommandResult.Status.OK; + String result = ""; + + try { + if (action.equals("setStorage")) { + this.setStorage(args.getString(0)); + } + else if (action.equals("openDatabase")) { + this.openDatabase(args.getString(0), args.getString(1), args.getString(2), args.getLong(3)); + } + else if (action.equals("executeSql")) { + JSONArray a = args.getJSONArray(1); + int len = a.length(); + String[] s = new String[len]; + for (int i=0; i list = this.sensorManager.getSensorList(Sensor.TYPE_TEMPERATURE); if (list.size() > 0) { @@ -42,7 +125,7 @@ public class TempListener extends Module implements SensorEventListener { public void onSensorChanged(SensorEvent event) { // We want to know what temp this is. float temp = event.values[0]; - mCtx.sendJavascript("gotTemp(" + temp + ");"); + this.ctx.sendJavascript("gotTemp(" + temp + ");"); } } \ No newline at end of file diff --git a/framework/src/com/phonegap/api/Command.java b/framework/src/com/phonegap/api/Command.java index 5c28f43d..b155844b 100644 --- a/framework/src/com/phonegap/api/Command.java +++ b/framework/src/com/phonegap/api/Command.java @@ -2,7 +2,10 @@ package com.phonegap.api; import org.json.JSONArray; +import com.phonegap.DroidGap; + import android.content.Context; +import android.content.Intent; import android.webkit.WebView; /** @@ -29,7 +32,7 @@ public interface Command { * * @param ctx The context of the main Activity. */ - void setContext(Context ctx); + void setContext(DroidGap ctx); /** * Sets the main View of the application, this is the WebView within which @@ -38,4 +41,31 @@ public interface Command { * @param webView The PhoneGap WebView */ void setView(WebView webView); + + /** + * Called when the system is about to start resuming a previous activity. + */ + void onPause(); + + /** + * Called when the activity will start interacting with the user. + */ + void onResume(); + + /** + * The final call you receive before your activity is destroyed. + */ + void onDestroy(); + + /** + * Called when an activity you launched exits, giving you the requestCode you started it with, + * the resultCode it returned, and any additional data from it. + * + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + */ + void onActivityResult(int requestCode, int resultCode, Intent intent); + } diff --git a/framework/src/com/phonegap/api/CommandManager.java b/framework/src/com/phonegap/api/CommandManager.java old mode 100644 new mode 100755 index 924af9c8..02ce21fc --- a/framework/src/com/phonegap/api/CommandManager.java +++ b/framework/src/com/phonegap/api/CommandManager.java @@ -1,9 +1,13 @@ package com.phonegap.api; +import java.util.HashMap; +import java.util.Map.Entry; + import org.json.JSONArray; import org.json.JSONException; import android.content.Context; +import android.content.Intent; import android.webkit.WebView; import com.phonegap.DroidGap; @@ -18,12 +22,13 @@ import com.phonegap.DroidGap; * */ public final class CommandManager { - private Command[] commands; - private final Context ctx; + private HashMap commands = new HashMap(); + + private final DroidGap ctx; private final WebView app; - public CommandManager(WebView app, Context ctx) { + public CommandManager(WebView app, DroidGap ctx) { this.ctx = ctx; this.app = app; } @@ -49,18 +54,15 @@ public final class CommandManager { * is called once the plugin code has executed. * @return JSON encoded string with a response message and status. */ - public String exec(final String clazz, final String action, final String callbackId, - final String jsonArgs, final boolean async) { + public String exec(final String clazz, final String action, final String callbackId, final String jsonArgs, final boolean async) { CommandResult cr = null; try { final JSONArray args = new JSONArray(jsonArgs); Class c = getClassByName(clazz); if (isPhoneGapCommand(c)) { // Create a new instance of the plugin and set the context and webview - final Command plugin = (Command)c.newInstance(); - plugin.setContext(this.ctx); - plugin.setView(this.app); - + final Command plugin = this.addCommand(clazz); + final DroidGap ctx = this.ctx; if (async) { // Run this on a different thread so that this one can return back to JS Thread thread = new Thread(new Runnable() { @@ -69,9 +71,9 @@ public final class CommandManager { CommandResult cr = plugin.execute(action, args); // Check the status for 0 (success) or otherwise if (cr.getStatus() == 0) { - app.loadUrl(cr.toSuccessCallbackString(callbackId)); + ctx.sendJavascript(cr.toSuccessCallbackString(callbackId)); } else { - app.loadUrl(cr.toErrorCallbackString(callbackId)); + ctx.sendJavascript(cr.toErrorCallbackString(callbackId)); } } }); @@ -84,16 +86,13 @@ public final class CommandManager { } } catch (ClassNotFoundException e) { cr = new CommandResult(CommandResult.Status.CLASS_NOT_FOUND_EXCEPTION); - } catch (IllegalAccessException e) { - cr = new CommandResult(CommandResult.Status.ILLEGAL_ACCESS_EXCEPTION); - } catch (InstantiationException e) { - cr = new CommandResult(CommandResult.Status.INSTANTIATION_EXCEPTION); } catch (JSONException e) { + System.out.println("ERROR: "+e.toString()); cr = new CommandResult(CommandResult.Status.JSON_EXCEPTION); } // if async we have already returned at this point unless there was an error... if (async) { - app.loadUrl(cr.toErrorCallbackString(callbackId)); + ctx.sendJavascript(cr.toErrorCallbackString(callbackId)); } return ( cr != null ? cr.getJSONString() : "{ status: 0, message: 'all good' }" ); } @@ -127,4 +126,80 @@ public final class CommandManager { } return isCommand; } + + /** + * Add command to be loaded and cached. + * If command is already created, then just return it. + * + * @param className The class to load + * @return The command + */ + public Command addCommand(String className) { + if (this.commands.containsKey(className)) { + return this.getCommand(className); + } + try { + Command command = (Command)Class.forName(className).newInstance(); + this.commands.put(className, command); + command.setContext((DroidGap)this.ctx); + command.setView(this.app); + return command; + } + catch (Exception e) { + e.printStackTrace(); + System.out.println("Error adding command "+className+"."); + } + return null; + } + + /** + * Get the loaded command. + * + * @param className The class of the loaded command. + * @return + */ + public Command getCommand(String className) { + Command command = this.commands.get(className); + return command; + } + + /** + * Called when the system is about to start resuming a previous activity. + */ + public void onPause() { + java.util.Set> s = this.commands.entrySet(); + java.util.Iterator> it = s.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + Command command = entry.getValue(); + command.onPause(); + } + } + + /** + * Called when the activity will start interacting with the user. + */ + public void onResume() { + java.util.Set> s = this.commands.entrySet(); + java.util.Iterator> it = s.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + Command command = entry.getValue(); + command.onResume(); + } + } + + /** + * The final call you receive before your activity is destroyed. + */ + public void onDestroy() { + java.util.Set> s = this.commands.entrySet(); + java.util.Iterator> it = s.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + Command command = entry.getValue(); + command.onDestroy(); + } + } + } \ No newline at end of file diff --git a/framework/src/com/phonegap/api/CommandResult.java b/framework/src/com/phonegap/api/CommandResult.java old mode 100644 new mode 100755 index 5664923a..f8a58cde --- a/framework/src/com/phonegap/api/CommandResult.java +++ b/framework/src/com/phonegap/api/CommandResult.java @@ -21,6 +21,19 @@ public class CommandResult { this.message = message.toString(); } + public CommandResult(Status status, int i) { + this.status = status.ordinal(); + this.message = ""+i; + } + public CommandResult(Status status, float f) { + this.status = status.ordinal(); + this.message = ""+f; + } + public CommandResult(Status status, boolean b) { + this.status = status.ordinal(); + this.message = ""+b; + } + public int getStatus() { return status; }