Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

android pigeon

  • Loading branch information...
commit 53dc5bc2332abf93ee1d0ba601e2671a7763d18b 1 parent 78c5443
alunny authored
Showing with 3,800 additions and 0 deletions.
  1. +8 −0 android/.classpath
  2. +33 −0 android/.project
  3. +33 −0 android/AndroidManifest.xml
  4. BIN  android/assets/www/assets/bar.png
  5. BIN  android/assets/www/assets/button.png
  6. BIN  android/assets/www/assets/header.png
  7. BIN  android/assets/www/assets/login_button.png
  8. BIN  android/assets/www/assets/tweet_background.png
  9. BIN  android/assets/www/assets/tweet_button.png
  10. +92 −0 android/assets/www/index.html
  11. +166 −0 android/assets/www/master.css
  12. +1,230 −0 android/assets/www/script/phonegap.js
  13. +214 −0 android/assets/www/script/pigeon.js
  14. +87 −0 android/assets/www/script/sql.js
  15. +1 −0  android/assets/www/script/xui-min.js
  16. BIN  android/bin/Pigeon.apk
  17. BIN  android/bin/classes.dex
  18. BIN  android/bin/com/pigeon/app/AccelListener.class
  19. BIN  android/bin/com/pigeon/app/AccelTuple.class
  20. BIN  android/bin/com/pigeon/app/AudioHandler$1.class
  21. BIN  android/bin/com/pigeon/app/AudioHandler.class
  22. BIN  android/bin/com/pigeon/app/CameraLauncher.class
  23. BIN  android/bin/com/pigeon/app/CameraPreview$1.class
  24. BIN  android/bin/com/pigeon/app/CameraPreview$2.class
  25. BIN  android/bin/com/pigeon/app/CameraPreview$3.class
  26. BIN  android/bin/com/pigeon/app/CameraPreview.class
  27. BIN  android/bin/com/pigeon/app/CompassListener.class
  28. BIN  android/bin/com/pigeon/app/DirectoryManager.class
  29. BIN  android/bin/com/pigeon/app/DroidGap$GapClient.class
  30. BIN  android/bin/com/pigeon/app/DroidGap.class
  31. BIN  android/bin/com/pigeon/app/FileUtils.class
  32. BIN  android/bin/com/pigeon/app/GeoBroker.class
  33. BIN  android/bin/com/pigeon/app/GeoListener.class
  34. BIN  android/bin/com/pigeon/app/GeoTuple.class
  35. BIN  android/bin/com/pigeon/app/GpsListener.class
  36. BIN  android/bin/com/pigeon/app/HttpHandler.class
  37. BIN  android/bin/com/pigeon/app/NetworkListener.class
  38. BIN  android/bin/com/pigeon/app/Orientation.class
  39. BIN  android/bin/com/pigeon/app/PhoneGap.class
  40. BIN  android/bin/com/pigeon/app/R$attr.class
  41. BIN  android/bin/com/pigeon/app/R$drawable.class
  42. BIN  android/bin/com/pigeon/app/R$id.class
  43. BIN  android/bin/com/pigeon/app/R$layout.class
  44. BIN  android/bin/com/pigeon/app/R$raw.class
  45. BIN  android/bin/com/pigeon/app/R$string.class
  46. BIN  android/bin/com/pigeon/app/R.class
  47. BIN  android/bin/com/pigeon/app/SmsListener.class
  48. BIN  android/bin/com/pigeon/app/VideoPreview.class
  49. BIN  android/bin/resources.ap_
  50. +61 −0 android/build.xml
  51. +14 −0 android/default.properties
  52. +35 −0 android/gen/com/pigeon/app/R.java
  53. BIN  android/libs/commons-codec-1.3.jar
  54. BIN  android/res/drawable/icon.png
  55. +11 −0 android/res/layout/main.xml
  56. +23 −0 android/res/layout/preview.xml
  57. BIN  android/res/raw/bird.mp3
  58. BIN  android/res/raw/off.mp3
  59. BIN  android/res/raw/on.mp3
  60. +6 −0 android/res/values/strings.xml
  61. +68 −0 android/src/com/pigeon/app/AccelListener.java
  62. +29 −0 android/src/com/pigeon/app/AccelTuple.java
  63. +186 −0 android/src/com/pigeon/app/AudioHandler.java
  64. +34 −0 android/src/com/pigeon/app/CameraLauncher.java
  65. +192 −0 android/src/com/pigeon/app/CameraPreview.java
  66. +54 −0 android/src/com/pigeon/app/CompassListener.java
  67. +126 −0 android/src/com/pigeon/app/DirectoryManager.java
  68. +167 −0 android/src/com/pigeon/app/DroidGap.java
  69. +129 −0 android/src/com/pigeon/app/FileUtils.java
  70. +41 −0 android/src/com/pigeon/app/GeoBroker.java
  71. +76 −0 android/src/com/pigeon/app/GeoListener.java
  72. +32 −0 android/src/com/pigeon/app/GeoTuple.java
  73. +99 −0 android/src/com/pigeon/app/GpsListener.java
  74. +65 −0 android/src/com/pigeon/app/HttpHandler.java
  75. +102 −0 android/src/com/pigeon/app/NetworkListener.java
  76. +69 −0 android/src/com/pigeon/app/Orientation.java
  77. +241 −0 android/src/com/pigeon/app/PhoneGap.java
  78. +68 −0 android/src/com/pigeon/app/SmsListener.java
  79. +8 −0 android/src/com/pigeon/app/VideoPreview.java
View
8 android/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="lib" path="libs/commons-codec-1.3.jar"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
33 android/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>PhoneGap</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
33 android/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:versionCode="2" android:versionName="0.0.1" package="com.pigeon.app">
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.VIBRATE" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.RECEIVE_SMS" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <application android:icon="@drawable/icon" android:label="@string/app_name"
+ android:debuggable="true">
+ <activity android:name=".DroidGap"
+ android:label="@string/app_name" android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".CameraPreview"
+ android:label="@string/app_name" android:screenOrientation="landscape"
+ android:configChanges="orientation|keyboardHidden">
+ <action android:name="android.intent.action.PICK" />
+ </activity>
+ </application>
+ <uses-sdk android:minSdkVersion="4" />
+
+</manifest>
View
BIN  android/assets/www/assets/bar.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  android/assets/www/assets/button.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  android/assets/www/assets/header.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  android/assets/www/assets/login_button.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  android/assets/www/assets/tweet_background.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  android/assets/www/assets/tweet_button.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
92 android/assets/www/index.html
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <meta name="viewport" content="width=320; user-scalable=no" />
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+ <title>Pigeon - PhoneGap Twitter App</title>
+ <script type="text/javascript" src="script/phonegap.js"></script>
+ <script type="text/javascript" src="script/xui-min.js"></script>
+ <script type="text/javascript" src="script/pigeon.js"></script>
+ <script type="text/javascript" src="script/sql.js"></script>
+ <link rel="stylesheet" type="text/css" href="master.css" media="screen" />
+ </head>
+ <body>
+
+ <!--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Header
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
+
+ <div id="header">
+
+ <div id="login_screen" class="panel" >
+ <form id="login_form" action="#">
+
+ <div class="left_column">
+ <h1>Pigeon</h1>
+ <a href="#" class="submission" id="login_link"></a>
+ </div>
+
+ <div id="login_input">
+ <label>Username</label><input type="text" id="user_field" name="Username" length="15" />
+ <label>Password</label><input type="password" id="pass_field" name="Password" length="15" />
+ </div>
+ </form>
+ </div>
+ <div id="post_new_tweet" class="panel">
+
+ <div class="left_column">
+ <h1>Pigeon</h1>
+ <a href="#" class="submission" id="tweet_link"></a>
+ </div>
+ <textarea id="tweet_content" rows="3" cols="45" maxlength="140"></textarea>
+ </div>
+
+ <form id="search_form" action="#" style="display:none" class="panel">
+
+ <div class="left_column">
+ <h1>Pigeon</h1>
+ <a href="#" class="submission" id="search_link">Search</a>
+ </div>
+
+ <div id="search_input">
+ <label>Search</label><input type="text" id="query" name="Query" length="15" />
+ </div>
+ </form>
+
+ </div>
+
+
+ <!--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Menu
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
+
+ <div id="menu_options">
+ <ul>
+ <li><a href="#" id="menu_friends">Friends</a></li>
+ <li><a href="#" id="menu_search">Search</a></li>
+ <li><a href="#" id="menu_local">Local</a></li>
+ <li><a href="#" id="menu_dms">DMs</a></li>
+ <li><a href="#" id="menu_logout">Logout</a></li>
+ </ul>
+ </div>
+
+
+ <!--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Content
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
+
+ <div id="dm_content" class="twt_panel">
+ </div>
+ <div id="content" class="twt_panel">
+ </div>
+ <div id="local_content" class="twt_panel">
+ <h2 id="local_header">Tweets Near You</h2>
+ <div id="local_results"></div>
+ </div>
+ <div id="search_panel" class="twt_panel">
+ <h2 id="search_header">Search Results for "<span id="search_term"></span>"</h2>
+ <div id="search_results"></div>
+ </div>
+ </body>
+</html>
View
166 android/assets/www/master.css
@@ -0,0 +1,166 @@
+body {
+ background: #3F3F40 url(assets/tweet_background.png) 0 150px repeat-x;
+ color:#fff;
+ font-family:Helvetica;
+ font-size:72%;
+ line-height:1.5em;
+ margin:0;
+ -webkit-text-size-adjust: none;
+}
+
+/*------------------------------------------------------------------------
+ General
+--------------------------------------------------------------------------*/
+
+h1, h2 {
+ margin: 0;
+}
+
+a, a:visited {
+ font-weight: bold;
+ color: #fff;
+ text-decoration: none;
+}
+
+/*------------------------------------------------------------------------
+ Form
+--------------------------------------------------------------------------*/
+
+#tweet_content, #login_input, #search_input {
+ width: 200px;
+}
+
+#login_input {
+ padding-top: 11px;
+}
+
+#search_input {
+ padding-top: 40px;
+}
+
+label {
+ vertical-align: baseline;
+ width: 62px;
+ margin-right: 5px;
+ text-align: right;
+ float: left;
+}
+
+#user_field, #pass_field, #query {
+ width: 110px;
+ height: 20px;
+ margin-bottom: 8px;
+}
+
+.left_column {
+ float: right;
+ width: 92px;
+}
+
+.login_input {
+ text-align: right;
+}
+
+#tweet_content {
+ height: 64px;
+}
+
+#tweet_link, #login_link, #search_link {
+ float: right;
+ background: url(assets/tweet_button.png) top left no-repeat;
+ height: 48px;
+ width: 80px;
+ margin-top: 12px;
+ color: #005d98;
+ font-weight: normal;
+ text-align: center;
+ line-height: 4.0em;
+ padding-left: 10px;
+}
+
+#login_link {
+ background: url(assets/login_button.png) top left no-repeat;
+}
+
+#search_link {
+ background: url(assets/button.png) top left no-repeat;
+}
+
+/*------------------------------------------------------------------------
+ Layout
+--------------------------------------------------------------------------*/
+
+#header {
+ background: url(assets/header.png) repeat-x top left;
+ padding: 24px 8px;
+ height: 66px;
+}
+
+#header h1 {
+ float: right;
+}
+
+
+/*------------------------------------------------------------------------
+ Menu
+--------------------------------------------------------------------------*/
+
+#menu_options {
+ background: url(assets/bar.png) repeat-x top left;
+ margin: 0;
+ height: 20px;
+ padding: 8px;
+}
+
+ul {
+ margin: 0;
+}
+
+#menu_options ul li {
+ display: inline;
+ margin-right: 8px;
+}
+
+#menu_options ul li a {
+ font-size: 11px;
+ padding: 4px;
+ display: block-inline;
+}
+
+
+/*------------------------------------------------------------------------
+ Content
+--------------------------------------------------------------------------*/
+
+
+.twt_panel, #post_new_tweet {
+ display: none;
+}
+
+.twt_panel {
+ width: 320px;
+}
+
+.tweet {
+ background: url(assets/tweet_background.png) top left repeat-x;
+ display: block;
+ min-height: 64px;
+ padding: 4px 0;
+ overflow: hidden;
+}
+.tweet img {
+ float: left;
+ margin: 4px 8px;
+ width: 48px;
+ height: 48px;
+ border: 1px solid #666;
+}
+
+.tweet .user_name {
+ font-weight: bold;
+ color: #ccc;
+}
+
+.tweet p {
+ margin: 0 0 0 64px;
+}
View
1,230 android/assets/www/script/phonegap.js
@@ -0,0 +1,1230 @@
+if (typeof(DeviceInfo) != 'object')
+ DeviceInfo = {};
+
+/**
+ * This represents the PhoneGap API itself, and provides a global namespace for accessing
+ * information about the state of PhoneGap.
+ * @class
+ */
+PhoneGap = {
+ queue: {
+ ready: true,
+ commands: [],
+ timer: null
+ },
+ _constructors: []
+};
+
+/**
+ * Boolean flag indicating if the PhoneGap API is available and initialized.
+ */
+PhoneGap.available = DeviceInfo.uuid != undefined;
+
+/**
+ * Add an initialization function to a queue that ensures it will run and initialize
+ * application constructors only once PhoneGap has been initialized.
+ * @param {Function} func The function callback you want run once PhoneGap is initialized
+ */
+PhoneGap.addConstructor = function(func) {
+ var state = document.readyState;
+ if (state != 'loaded' && state != 'complete')
+ PhoneGap._constructors.push(func);
+ else
+ func();
+};
+(function() {
+ var timer = setInterval(function() {
+ var state = document.readyState;
+ if (state != 'loaded' && state != 'complete')
+ return;
+ clearInterval(timer);
+ while (PhoneGap._constructors.length > 0) {
+ var constructor = PhoneGap._constructors.shift();
+ try {
+ constructor();
+ } catch(e) {
+ if (typeof(debug['log']) == 'function')
+ debug.log("Failed to run constructor: " + debug.processMessage(e));
+ else
+ alert("Failed to run constructor: " + e.message);
+ }
+ }
+ }, 1);
+})();
+
+
+/**
+ * Execute a PhoneGap command in a queued fashion, to ensure commands do not
+ * execute with any race conditions, and only run when PhoneGap is ready to
+ * recieve them.
+ * @param {String} command Command to be run in PhoneGap, e.g. "ClassName.method"
+ * @param {String[]} [args] Zero or more arguments to pass to the method
+ */
+PhoneGap.exec = function() {
+ PhoneGap.queue.commands.push(arguments);
+ if (PhoneGap.queue.timer == null)
+ PhoneGap.queue.timer = setInterval(PhoneGap.run_command, 10);
+};
+/**
+ * Internal function used to dispatch the request to PhoneGap. This needs to be implemented per-platform to
+ * ensure that methods are called on the phone in a way appropriate for that device.
+ * @private
+ */
+PhoneGap.run_command = function() {
+};
+
+/**
+ * This class contains acceleration information
+ * @constructor
+ * @param {Number} x The force applied by the device in the x-axis.
+ * @param {Number} y The force applied by the device in the y-axis.
+ * @param {Number} z The force applied by the device in the z-axis.
+ */
+function Acceleration(x, y, z) {
+ /**
+ * The force applied by the device in the x-axis.
+ */
+ this.x = x;
+ /**
+ * The force applied by the device in the y-axis.
+ */
+ this.y = y;
+ /**
+ * The force applied by the device in the z-axis.
+ */
+ this.z = z;
+ /**
+ * The time that the acceleration was obtained.
+ */
+ this.timestamp = new Date().getTime();
+}
+
+/**
+ * This class specifies the options for requesting acceleration data.
+ * @constructor
+ */
+function AccelerationOptions() {
+ /**
+ * The timeout after which if acceleration data cannot be obtained the errorCallback
+ * is called.
+ */
+ this.timeout = 10000;
+}
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+function Accelerometer() {
+ /**
+ * The last known acceleration.
+ */
+ this.lastAcceleration = null;
+}
+
+/**
+ * Asynchronously aquires the current acceleration.
+ * @param {Function} successCallback The function to call when the acceleration
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the acceleration data.
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
+ * such as timeout.
+ */
+Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) {
+ // If the acceleration is available then call success
+ // If the acceleration is not available then call error
+
+ // Created for iPhone, Iphone passes back _accel obj litteral
+ if (typeof successCallback == "function") {
+ var accel = new Acceleration(_accel.x,_accel.y,_accel.z);
+ Accelerometer.lastAcceleration = accel;
+ successCallback(accel);
+ }
+}
+
+/**
+ * Asynchronously aquires the acceleration repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the acceleration
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the acceleration data.
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
+ * such as timeout.
+ */
+
+Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) {
+ this.getCurrentAcceleration(successCallback, errorCallback, options);
+ // TODO: add the interval id to a list so we can clear all watches
+ var frequency = (options != undefined)? options.frequency : 10000;
+ return setInterval(function() {
+ navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options);
+ }, frequency);
+}
+
+/**
+ * Clears the specified accelerometer watch.
+ * @param {String} watchId The ID of the watch returned from #watchAcceleration.
+ */
+Accelerometer.prototype.clearWatch = function(watchId) {
+ clearInterval(watchId);
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer();
+});
+/**
+ * This class provides access to the device camera.
+ * @constructor
+ */
+function Camera() {
+
+}
+
+/**
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+Camera.prototype.getPicture = function(successCallback, errorCallback, options) {
+
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.camera == "undefined") navigator.camera = new Camera();
+});
+/**
+ * This class provides access to the device contacts.
+ * @constructor
+ */
+
+function Contact(jsonObject) {
+ this.firstName = "";
+ this.lastName = "";
+ this.name = "";
+ this.phones = {};
+ this.emails = {};
+ this.address = "";
+}
+
+Contact.prototype.displayName = function()
+{
+ // TODO: can be tuned according to prefs
+ return this.name;
+}
+
+function ContactManager() {
+ // Dummy object to hold array of contacts
+ this.contacts = [];
+ this.timestamp = new Date().getTime();
+}
+
+ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) {
+ // Interface
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.ContactManager == "undefined") navigator.ContactManager = new ContactManager();
+});
+/**
+ * This class provides access to the debugging console.
+ * @constructor
+ */
+function DebugConsole() {
+}
+
+/**
+ * Utility function for rendering and indenting strings, or serializing
+ * objects to a string capable of being printed to the console.
+ * @param {Object|String} message The string or object to convert to an indented string
+ * @private
+ */
+DebugConsole.prototype.processMessage = function(message) {
+ if (typeof(message) != 'object') {
+ return message;
+ } else {
+ /**
+ * @function
+ * @ignore
+ */
+ function indent(str) {
+ return str.replace(/^/mg, " ");
+ }
+ /**
+ * @function
+ * @ignore
+ */
+ function makeStructured(obj) {
+ var str = "";
+ for (var i in obj) {
+ try {
+ if (typeof(obj[i]) == 'object') {
+ str += i + ":\n" + indent(makeStructured(obj[i])) + "\n";
+ } else {
+ str += i + " = " + indent(String(obj[i])).replace(/^ /, "") + "\n";
+ }
+ } catch(e) {
+ str += i + " = EXCEPTION: " + e.message + "\n";
+ }
+ }
+ return str;
+ }
+ return "Object:\n" + makeStructured(message);
+ }
+};
+
+/**
+ * Print a normal log message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.log = function(message) {
+};
+
+/**
+ * Print a warning message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.warn = function(message) {
+};
+
+/**
+ * Print an error message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.error = function(message) {
+};
+
+PhoneGap.addConstructor(function() {
+ window.debug = new DebugConsole();
+});
+/**
+ * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+ this.available = PhoneGap.available;
+ this.platform = null;
+ this.version = null;
+ this.name = null;
+ this.gap = null;
+ this.uuid = null;
+ try {
+ if (window.DroidGap) {
+ this.available = true;
+ this.uuid = window.DroidGap.getUuid();
+ this.version = window.DroidGap.getOSVersion();
+ this.gapVersion = window.DroidGap.getVersion();
+ this.platform = window.DroidGap.getPlatform();
+ this.name = window.DroidGap.getProductName();
+ } else {
+ this.platform = DeviceInfo.platform;
+ this.version = DeviceInfo.version;
+ this.name = DeviceInfo.name;
+ this.gap = DeviceInfo.gap;
+ this.uuid = DeviceInfo.uuid;
+ }
+ } catch(e) {
+ this.available = false;
+ }
+}
+
+PhoneGap.addConstructor(function() {
+ navigator.Device = window.Device = new Device();
+});
+/**
+ * This class provides generic read and write access to the mobile device file system.
+ */
+function File() {
+ /**
+ * The data of a file.
+ */
+ this.data = "";
+ /**
+ * The name of the file.
+ */
+ this.name = "";
+}
+
+/**
+ * Reads a file from the mobile device. This function is asyncronous.
+ * @param {String} fileName The name (including the path) to the file on the mobile device.
+ * The file name will likely be device dependent.
+ * @param {Function} successCallback The function to call when the file is successfully read.
+ * @param {Function} errorCallback The function to call when there is an error reading the file from the device.
+ */
+File.prototype.read = function(fileName, successCallback, errorCallback) {
+
+}
+
+/**
+ * Writes a file to the mobile device.
+ * @param {File} file The file to write to the device.
+ */
+File.prototype.write = function(file) {
+
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.file == "undefined") navigator.file = new File();
+});
+/**
+ * This class provides access to device GPS data.
+ * @constructor
+ */
+function Geolocation() {
+ /**
+ * The last known GPS position.
+ */
+ this.lastPosition = null;
+ this.lastError = null;
+ this.callbacks = {
+ onLocationChanged: [],
+ onError: []
+ };
+};
+
+/**
+ * Asynchronously aquires the current position.
+ * @param {Function} successCallback The function to call when the position
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the position data.
+ * @param {PositionOptions} options The options for getting the position data
+ * such as timeout.
+ */
+Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) {
+ var referenceTime = 0;
+ if (this.lastPosition)
+ referenceTime = this.lastPosition.timeout;
+ else
+ this.start(options);
+
+ var timeout = 20000;
+ var interval = 500;
+ if (typeof(options) == 'object' && options.interval)
+ interval = options.interval;
+
+ if (typeof(successCallback) != 'function')
+ successCallback = function() {};
+ if (typeof(errorCallback) != 'function')
+ errorCallback = function() {};
+
+ var dis = this;
+ var delay = 0;
+ var timer = setInterval(function() {
+ delay += interval;
+
+ if (typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) {
+ successCallback(dis.lastPosition);
+ clearInterval(timer);
+ } else if (delay >= timeout) {
+ errorCallback();
+ clearInterval(timer);
+ }
+ }, interval);
+};
+
+/**
+ * Asynchronously aquires the position repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the position
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the position data.
+ * @param {PositionOptions} options The options for getting the position data
+ * such as timeout and the frequency of the watch.
+ */
+Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) {
+ // Invoke the appropriate callback with a new Position object every time the implementation
+ // determines that the position of the hosting device has changed.
+
+ this.getCurrentPosition(successCallback, errorCallback, options);
+ var frequency = 10000;
+ if (typeof(options) == 'object' && options.frequency)
+ frequency = options.frequency;
+
+ var that = this;
+ return setInterval(function() {
+ that.getCurrentPosition(successCallback, errorCallback, options);
+ }, frequency);
+};
+
+
+/**
+ * Clears the specified position watch.
+ * @param {String} watchId The ID of the watch returned from #watchPosition.
+ */
+Geolocation.prototype.clearWatch = function(watchId) {
+ clearInterval(watchId);
+};
+
+/**
+ * Called by the geolocation framework when the current location is found.
+ * @param {PositionOptions} position The current position.
+ */
+Geolocation.prototype.setLocation = function(position) {
+ this.lastPosition = position;
+ for (var i = 0; i < this.callbacks.onLocationChanged.length; i++) {
+ var f = this.callbacks.onLocationChanged.shift();
+ f(position);
+ }
+};
+
+/**
+ * Called by the geolocation framework when an error occurs while looking up the current position.
+ * @param {String} message The text of the error message.
+ */
+Geolocation.prototype.setError = function(message) {
+ this.lastError = message;
+ for (var i = 0; i < this.callbacks.onError.length; i++) {
+ var f = this.callbacks.onError.shift();
+ f(message);
+ }
+};
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation();
+});
+/**
+ * This class provides access to device Compass data.
+ * @constructor
+ */
+function Compass() {
+ /**
+ * The last known Compass position.
+ */
+ this.lastHeading = null;
+ this.lastError = null;
+ this.callbacks = {
+ onHeadingChanged: [],
+ onError: []
+ };
+};
+
+/**
+ * Asynchronously aquires the current heading.
+ * @param {Function} successCallback The function to call when the heading
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the heading data.
+ * @param {PositionOptions} options The options for getting the heading data
+ * such as timeout.
+ */
+Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) {
+ if (this.lastHeading == null) {
+ this.start(options);
+ }
+ else
+ if (typeof successCallback == "function") {
+ successCallback(this.lastHeading);
+ }
+};
+
+/**
+ * Asynchronously aquires the heading repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the heading
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the heading data.
+ * @param {HeadingOptions} options The options for getting the heading data
+ * such as timeout and the frequency of the watch.
+ */
+Compass.prototype.watchHeading= function(successCallback, errorCallback, options) {
+ // Invoke the appropriate callback with a new Position object every time the implementation
+ // determines that the position of the hosting device has changed.
+
+ this.getCurrentHeading(successCallback, errorCallback, options);
+ var frequency = 100;
+ if (typeof(options) == 'object' && options.frequency)
+ frequency = options.frequency;
+
+ var self = this;
+ return setInterval(function() {
+ self.getCurrentHeading(successCallback, errorCallback, options);
+ }, frequency);
+};
+
+
+/**
+ * Clears the specified heading watch.
+ * @param {String} watchId The ID of the watch returned from #watchHeading.
+ */
+Compass.prototype.clearWatch = function(watchId) {
+ clearInterval(watchId);
+};
+
+
+/**
+ * Called by the geolocation framework when the current heading is found.
+ * @param {HeadingOptions} position The current heading.
+ */
+Compass.prototype.setHeading = function(heading) {
+ this.lastHeading = heading;
+ for (var i = 0; i < this.callbacks.onHeadingChanged.length; i++) {
+ var f = this.callbacks.onHeadingChanged.shift();
+ f(heading);
+ }
+};
+
+/**
+ * Called by the geolocation framework when an error occurs while looking up the current position.
+ * @param {String} message The text of the error message.
+ */
+Compass.prototype.setError = function(message) {
+ this.lastError = message;
+ for (var i = 0; i < this.callbacks.onError.length; i++) {
+ var f = this.callbacks.onError.shift();
+ f(message);
+ }
+};
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.compass == "undefined") navigator.compass = new Compass();
+});
+/**
+ * This class provides access to native mapping applications on the device.
+ */
+function Map() {
+
+}
+
+/**
+ * Shows a native map on the device with pins at the given positions.
+ * @param {Array} positions
+ */
+Map.prototype.show = function(positions) {
+
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.map == "undefined") navigator.map = new Map();
+});
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ * @constructor
+ */
+function Media(src, successCallback, errorCallback) {
+ this.src = src;
+ this.successCallback = successCallback;
+ this.errorCallback = errorCallback;
+}
+
+Media.prototype.record = function() {
+}
+
+Media.prototype.play = function() {
+}
+
+Media.prototype.pause = function() {
+}
+
+Media.prototype.stop = function() {
+}
+
+
+/**
+ * This class contains information about any Media errors.
+ * @constructor
+ */
+function MediaError() {
+ this.code = null,
+ this.message = "";
+}
+
+MediaError.MEDIA_ERR_ABORTED = 1;
+MediaError.MEDIA_ERR_NETWORK = 2;
+MediaError.MEDIA_ERR_DECODE = 3;
+MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
+
+
+//if (typeof navigator.audio == "undefined") navigator.audio = new Media(src);
+/**
+ * This class provides access to notifications on the device.
+ */
+function Notification() {
+
+}
+
+/**
+ * Open a native alert dialog, with a customizable title and button text.
+ * @param {String} message Message to print in the body of the alert
+ * @param {String} [title="Alert"] Title of the alert dialog (default: Alert)
+ * @param {String} [buttonLabel="OK"] Label of the close button (default: OK)
+ */
+Notification.prototype.alert = function(message, title, buttonLabel) {
+ // Default is to use a browser alert; this will use "index.html" as the title though
+ alert(message);
+};
+
+/**
+ * Start spinning the activity indicator on the statusbar
+ */
+Notification.prototype.activityStart = function() {
+};
+
+/**
+ * Stop spinning the activity indicator on the statusbar, if it's currently spinning
+ */
+Notification.prototype.activityStop = function() {
+};
+
+/**
+ * Causes the device to blink a status LED.
+ * @param {Integer} count The number of blinks.
+ * @param {String} colour The colour of the light.
+ */
+Notification.prototype.blink = function(count, colour) {
+
+};
+
+/**
+ * Causes the device to vibrate.
+ * @param {Integer} mills The number of milliseconds to vibrate for.
+ */
+Notification.prototype.vibrate = function(mills) {
+
+};
+
+/**
+ * Causes the device to beep.
+ * @param {Integer} count The number of beeps.
+ * @param {Integer} volume The volume of the beep.
+ */
+Notification.prototype.beep = function(count, volume) {
+
+};
+
+// TODO: of course on Blackberry and Android there notifications in the UI as well
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.notification == "undefined") navigator.notification = new Notification();
+});
+
+/**
+ * This class provides access to the device orientation.
+ * @constructor
+ */
+function Orientation() {
+ /**
+ * The current orientation, or null if the orientation hasn't changed yet.
+ */
+ this.currentOrientation = null;
+}
+
+/**
+ * Set the current orientation of the phone. This is called from the device automatically.
+ *
+ * When the orientation is changed, the DOMEvent \c orientationChanged is dispatched against
+ * the document element. The event has the property \c orientation which can be used to retrieve
+ * the device's current orientation, in addition to the \c Orientation.currentOrientation class property.
+ *
+ * @param {Number} orientation The orientation to be set
+ */
+Orientation.prototype.setOrientation = function(orientation) {
+ Orientation.currentOrientation = orientation;
+ var e = document.createEvent('Events');
+ e.initEvent('orientationChanged', 'false', 'false');
+ e.orientation = orientation;
+ document.dispatchEvent(e);
+};
+
+/**
+ * Asynchronously aquires the current orientation.
+ * @param {Function} successCallback The function to call when the orientation
+ * is known.
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the orientation.
+ */
+Orientation.prototype.getCurrentOrientation = function(successCallback, errorCallback) {
+ // If the position is available then call success
+ // If the position is not available then call error
+};
+
+/**
+ * Asynchronously aquires the orientation repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the orientation
+ * data is available.
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the orientation data.
+ */
+Orientation.prototype.watchOrientation = function(successCallback, errorCallback) {
+ // Invoke the appropriate callback with a new Position object every time the implementation
+ // determines that the position of the hosting device has changed.
+ this.getCurrentPosition(successCallback, errorCallback);
+ return setInterval(function() {
+ navigator.orientation.getCurrentOrientation(successCallback, errorCallback);
+ }, 10000);
+};
+
+/**
+ * Clears the specified orientation watch.
+ * @param {String} watchId The ID of the watch returned from #watchOrientation.
+ */
+Orientation.prototype.clearWatch = function(watchId) {
+ clearInterval(watchId);
+};
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation();
+});
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} acc
+ * @param {Object} alt
+ * @param {Object} altacc
+ * @param {Object} head
+ * @param {Object} vel
+ * @constructor
+ */
+function Position(coords, timestamp) {
+ this.coords = coords;
+ this.timestamp = new Date().getTime();
+}
+
+function Coordinates(lat, lng, alt, acc, head, vel) {
+ /**
+ * The latitude of the position.
+ */
+ this.latitude = lat;
+ /**
+ * The longitude of the position,
+ */
+ this.longitude = lng;
+ /**
+ * The accuracy of the position.
+ */
+ this.accuracy = acc;
+ /**
+ * The altitude of the position.
+ */
+ this.altitude = alt;
+ /**
+ * The direction the device is moving at the position.
+ */
+ this.heading = head;
+ /**
+ * The velocity with which the device is moving at the position.
+ */
+ this.speed = vel;
+}
+
+/**
+ * This class specifies the options for requesting position data.
+ * @constructor
+ */
+function PositionOptions() {
+ /**
+ * Specifies the desired position accuracy.
+ */
+ this.enableHighAccuracy = true;
+ /**
+ * The timeout after which if position data cannot be obtained the errorCallback
+ * is called.
+ */
+ this.timeout = 10000;
+}
+
+/**
+ * This class contains information about any GSP errors.
+ * @constructor
+ */
+function PositionError() {
+ this.code = null;
+ this.message = "";
+}
+
+PositionError.UNKNOWN_ERROR = 0;
+PositionError.PERMISSION_DENIED = 1;
+PositionError.POSITION_UNAVAILABLE = 2;
+PositionError.TIMEOUT = 3;
+/**
+ * This class provides access to the device SMS functionality.
+ * @constructor
+ */
+function Sms() {
+
+}
+
+/**
+ * Sends an SMS message.
+ * @param {Integer} number The phone number to send the message to.
+ * @param {String} message The contents of the SMS message to send.
+ * @param {Function} successCallback The function to call when the SMS message is sent.
+ * @param {Function} errorCallback The function to call when there is an error sending the SMS message.
+ * @param {PositionOptions} options The options for accessing the GPS location such as timeout and accuracy.
+ */
+Sms.prototype.send = function(number, message, successCallback, errorCallback, options) {
+
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.sms == "undefined") navigator.sms = new Sms();
+});
+/**
+ * This class provides access to the telephony features of the device.
+ * @constructor
+ */
+function Telephony() {
+
+}
+
+/**
+ * Calls the specifed number.
+ * @param {Integer} number The number to be called.
+ */
+Telephony.prototype.call = function(number) {
+
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony();
+});
+/**
+ * This class exposes mobile phone interface controls to JavaScript, such as
+ * native tab and tool bars, etc.
+ * @constructor
+ */
+function UIControls() {
+ this.tabBarTag = 0;
+ this.tabBarCallbacks = {};
+}
+
+/**
+ * Create a native tab bar that can have tab buttons added to it which can respond to events.
+ */
+UIControls.prototype.createTabBar = function() {};
+
+/**
+ * Show a tab bar. The tab bar has to be created first.
+ * @param {Object} [options] Options indicating how the tab bar should be shown:
+ * - \c height integer indicating the height of the tab bar (default: \c 49)
+ * - \c position specifies whether the tab bar will be placed at the \c top or \c bottom of the screen (default: \c bottom)
+ */
+UIControls.prototype.showTabBar = function(options) {};
+
+/**
+ * Hide a tab bar. The tab bar has to be created first.
+ */
+UIControls.prototype.hideTabBar = function(animate) {};
+
+/**
+ * Create a new tab bar item for use on a previously created tab bar. Use ::showTabBarItems to show the new item on the tab bar.
+ *
+ * If the supplied image name is one of the labels listed below, then this method will construct a tab button
+ * using the standard system buttons. Note that if you use one of the system images, that the \c title you supply will be ignored.
+ *
+ * <b>Tab Buttons</b>
+ * - tabButton:More
+ * - tabButton:Favorites
+ * - tabButton:Featured
+ * - tabButton:TopRated
+ * - tabButton:Recents
+ * - tabButton:Contacts
+ * - tabButton:History
+ * - tabButton:Bookmarks
+ * - tabButton:Search
+ * - tabButton:Downloads
+ * - tabButton:MostRecent
+ * - tabButton:MostViewed
+ * @param {String} name internal name to refer to this tab by
+ * @param {String} [title] title text to show on the tab, or null if no text should be shown
+ * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown
+ * @param {Object} [options] Options for customizing the individual tab item
+ * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden
+ */
+UIControls.prototype.createTabBarItem = function(name, label, image, options) {};
+
+/**
+ * Update an existing tab bar item to change its badge value.
+ * @param {String} name internal name used to represent this item when it was created
+ * @param {Object} options Options for customizing the individual tab item
+ * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden
+ */
+UIControls.prototype.updateTabBarItem = function(name, options) {};
+
+/**
+ * Show previously created items on the tab bar
+ * @param {String} arguments... the item names to be shown
+ * @param {Object} [options] dictionary of options, notable options including:
+ * - \c animate indicates that the items should animate onto the tab bar
+ * @see createTabBarItem
+ * @see createTabBar
+ */
+UIControls.prototype.showTabBarItems = function(tabs, options) {};
+
+/**
+ * Manually select an individual tab bar item, or nil for deselecting a currently selected tab bar item.
+ * @param {String} tabName the name of the tab to select, or null if all tabs should be deselected
+ * @see createTabBarItem
+ * @see showTabBarItems
+ */
+UIControls.prototype.selectTabBarItem = function(tab) {};
+
+/**
+ * Function called when a tab bar item has been selected.
+ * @param {Number} tag the tag number for the item that has been selected
+ */
+UIControls.prototype.tabBarItemSelected = function(tag) {
+ if (typeof(this.tabBarCallbacks[tag]) == 'function')
+ this.tabBarCallbacks[tag]();
+};
+
+/**
+ * Create a toolbar.
+ */
+UIControls.prototype.createToolBar = function() {};
+
+/**
+ * Function called when a tab bar item has been selected.
+ * @param {String} title the title to set within the toolbar
+ */
+UIControls.prototype.setToolBarTitle = function(title) {};
+
+PhoneGap.addConstructor(function() {
+ window.uicontrols = new UIControls();
+});
+/*
+* Since we can't guarantee that we will have the most recent, we just try our best!
+*
+* Also, the API doesn't specify which version is the best version of the API
+*/
+
+Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options)
+{
+ var position = Geo.getCurrentLocation();
+ this.global_success = successCallback;
+ this.fail = errorCallback;
+}
+
+
+// Run the global callback
+Geolocation.prototype.gotCurrentPosition = function(lat, lng, alt, altacc, head, vel, stamp)
+{
+ if (lat == "undefined" || lng == "undefined")
+ {
+ this.fail();
+ }
+ else
+ {
+ coords = new Coordinates(lat, lng, alt, altacc, head, vel);
+ loc = new Position(coords, stamp);
+ this.global_success(loc);
+ }
+}
+
+/*
+* This turns on the GeoLocator class, which has two listeners.
+* The listeners have their own timeouts, and run independently of this process
+* In this case, we return the key to the watch hash
+*/
+
+Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options)
+{
+ var frequency = (options != undefined)? options.frequency : 10000;
+
+ if (!this.listeners)
+ {
+ this.listeners = [];
+ }
+
+ var key = this.listeners.push( {"success" : successCallback, "fail" : failCallback }) - 1;
+
+ // TO-DO: Get the names of the method and pass them as strings to the Java.
+ return Geolocation.start(frequency, key);
+}
+
+/*
+ * Retrieve and stop this listener from listening to the GPS
+ *
+ */
+Geolocation.prototype.success = function(key, lat, lng, alt, altacc, head, vel, stamp)
+{
+ var coords = new Coordinates(lat, lng, alt, altacc, head, vel);
+ var loc = new Position(coords, stamp);
+ this.listeners[key].success(loc);
+}
+
+Geolocation.prototype.fail = function(key)
+{
+ this.listeners[key].fail();
+}
+
+Geolocation.prototype.clearWatch = function(watchId)
+{
+ Geo.stop(watchId);
+}
+Notification.prototype.vibrate = function(mills)
+{
+ DroidGap.vibrate(mills);
+}
+
+/*
+ * On the Android, we don't beep, we notify you with your
+ * notification! We shouldn't keep hammering on this, and should
+ * review what we want beep to do.
+ */
+
+Notification.prototype.beep = function(count, volume)
+{
+ DroidGap.beep(count);
+}
+// Need to define these for android
+_accel = {}
+_accel.x = 0;
+_accel.y = 0;
+_accel.z = 0;
+
+function gotAccel(x, y, z)
+{
+ _accel.x = x;
+ _accel.y = y;
+ _accel.z = z;
+}
+
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+function Accelerometer() {
+ /**
+ * The last known acceleration.
+ */
+ this.lastAcceleration = null;
+}
+
+/**
+ * Asynchronously aquires the current acceleration.
+ * @param {Function} successCallback The function to call when the acceleration
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the acceleration data.
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
+ * such as timeout.
+ */
+Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) {
+ // If the acceleration is available then call success
+ // If the acceleration is not available then call error
+
+ // Created for iPhone, Iphone passes back _accel obj litteral
+ if (typeof successCallback == "function") {
+ var accel = new Acceleration(_accel.x,_accel.y,_accel.z);
+ Accelerometer.lastAcceleration = accel;
+ successCallback(accel);
+ }
+}
+
+/**
+ * Asynchronously aquires the acceleration repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the acceleration
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the acceleration data.
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
+ * such as timeout.
+ */
+
+Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) {
+ // TODO: add the interval id to a list so we can clear all watches
+ var frequency = (options != undefined)? options.frequency : 10000;
+
+ Accel.start(frequency);
+ return setInterval(function() {
+ navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options);
+ }, frequency);
+}
+
+/**
+ * Clears the specified accelerometer watch.
+ * @param {String} watchId The ID of the watch returned from #watchAcceleration.
+ */
+Accelerometer.prototype.clearWatch = function(watchId) {
+ Accel.stop();
+ clearInterval(watchId);
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer();
+});
+/**
+ * This class provides access to the device camera.
+ * @constructor
+ */
+function Camera() {
+
+}
+
+/**
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+Camera.prototype.getPicture = function(successCallback, errorCallback, options) {
+
+ this.winCallback = successCallback;
+ this.failCallback = errorCallback;
+ if (options.quality)
+ {
+ GapCam.takePicture(options.quality);
+ }
+ else
+ {
+ GapCam.takePicture(80);
+ }
+}
+
+Camera.prototype.win = function(picture)
+{
+ this.winCallback(picture);
+}
+
+Camera.prototype.fail = function(err)
+{
+ this.failCallback(err);
+}
+
+PhoneGap.addConstructor(function() {
+ if (typeof navigator.camera == "undefined") navigator.camera = new Camera();
+});
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ * @constructor
+ */
+
+Media.prototype.playAudio = function(filename) {
+ PhoneGap.startPlayingiAudio(filename);
+}
+
+Media.prototype.stopAudio = function() {
+ PhoneGap.stopPlayingAudio();
+}
+
+File.prototype.read = function(fileName, successCallback, errorCallback) {
+ this.failCallback = errorCallback;
+ this.winCallback = successCallback;
+
+ FileUtil.read(fileName);
+}
+
+File.prototype.hasRead = function(data)
+{
+ if(data.substr("FAIL"))
+ this.failCallback(data);
+ else
+ this.winCallback(data);
+ end
+}
+
+/**
+ * Writes a file to the mobile device.
+ * @param {File} file The file to write to the device.
+ */
+File.prototype.write = function(file, str, successCallback, failCallback) {
+ this.winCallback = successCallback;
+ this.failCallback = failCallback;
+ var call = FileUtil.write(file, str);
+}
View
214 android/assets/www/script/pigeon.js
@@ -0,0 +1,214 @@
+var direct_messages_url = "http://www.twitter.com/direct_messages.json"
+var friends_timeline_url = "http://www.twitter.com/statuses/friends_timeline.json";
+var tweet_post_url = "http://www.twitter.com/statuses/update.json";
+var tweet_search_url = "http://search.twitter.com/search.json";
+var tweet_response = "";
+
+// Global Data Store
+x$.data = {};
+
+x$(window).load(function() {
+ x$("#tweet_link").click(function() {
+ var twt = document.getElementById("tweet_content").value;
+ post_tweet(twt,x$.data.m_user,x$.data.m_pass,"#content");
+ return false;
+ });
+
+ x$("#search_link").click(search_function);
+ x$("#search_form").on("submit",search_function);
+
+ x$("#login_link").click(login_function);
+ x$("#login_form").on("submit",login_function);
+
+ x$("#menu_local").click(function() {
+ load_local_tweets("#local_results");
+ show_panel("#local_content");
+ return false;
+ });
+
+ x$("#menu_dms").click(function() {
+ load_dms("#dm_content",x$.data.m_user,x$.data.m_pass);
+ show_panel("#dm_content");
+ return false;
+ });
+
+ x$("#menu_search").click(function() {
+ x$(".panel").css({display:'none'});
+ x$("#search_form").setStyle("display", "block");
+ return false;
+ });
+
+ x$("#menu_friends").click(function() {
+ load_tweets("#content",x$.data.m_user,x$.data.m_pass);
+ show_panel("#content");
+ return false;
+ });
+
+ x$("#menu_logout").click(function() {
+ x$("#content").html(" ");
+ x$(".panel").css({display:'none'});
+ x$("#login_screen").setStyle("display", "block");
+ document.getElementById('user_field').value = "";
+ document.getElementById('pass_field').value = "";
+ show_panel("#login_screen");
+ });
+});
+
+var load_dms = function(container_id,user,passw) {
+ x$(container_id).xhr(direct_messages_url,
+ { callback: function () { render_dms(container_id,this.responseText); },
+ headers: [{name:"Authorization",
+ value: "Basic " + btoa(user + ":" + passw)}]
+ });
+}
+
+var render_dms = function(container_id,new_tweets) {
+ var tweetstream = eval(new_tweets);
+ var i=0;
+ for (i=0; i<tweetstream.length; i++) {
+ x$(container_id).html("bottom",
+ format_tweet({
+ profile_image:tweetstream[i].sender.profile_image_url,
+ user_name:tweetstream[i].sender.name,
+ tweet_text:tweetstream[i].text
+ }));
+ }
+}
+
+var load_tweets = function(container_id,user,passw) {
+ x$("#login_screen").setStyle("display","none");
+
+ x$(container_id).xhr(friends_timeline_url,
+ { callback: function () { render_tweets(container_id, this.responseText); },
+ headers: [{name:"Authorization",
+ value: "Basic " + btoa(user + ":" + passw)}]
+ });
+}
+
+var render_tweets = function(container_id, new_tweets) {
+ var tweetstream = eval(new_tweets);
+ var i=0;
+ for (i=0; i<tweetstream.length; i++) {
+ x$(container_id).html("bottom",
+ format_tweet({
+ profile_image:tweetstream[i].user.profile_image_url,
+ user_name:tweetstream[i].user.name,
+ tweet_text:tweetstream[i].text
+ }));
+ }
+}
+
+var format_tweet = function(options) {
+ var tweetstring = "<div class=\"tweet\"\n<img src=\"{PROFILE_IMAGE}\" />\n<p class=\"user_name\">{USER_NAME}</p>\n <p class=\"tweet_text\">{TWEET_TEXT}</p>\n</div>";
+ tweetstring = tweetstring.replace("{PROFILE_IMAGE}",options.profile_image);
+ tweetstring = tweetstring.replace("{USER_NAME}",options.user_name);
+ tweetstring = tweetstring.replace("{TWEET_TEXT}",options.tweet_text);
+ return tweetstring;
+}
+
+var post_tweet = function(status,user,passw,container_id) {
+ var params = "status=" + encodeURIComponent(status);
+ x$(container_id).xhr(tweet_post_url,
+ { callback: function() { render_new_tweet(this.responseText); },
+ headers: [{name:"Authorization",
+ value: "Basic " + btoa(user + ":" + passw)},
+ {name:"Content-Length",
+ value: params.length},
+ {name:"Content-type",
+ value:"application/x-www-form-urlencoded"},
+ {name:"Connection",
+ value: "close"}],
+ method: "post",
+ data: params
+ });
+ navigator.notification.beep(2);
+}
+
+var render_new_tweet = function(new_tweet) {
+ try {
+ tweet_response = eval("[" + new_tweet + "]");
+ } catch (e) {
+ alert(e);
+ }
+ x$("#content").html("top",
+ format_tweet({
+ profile_image:tweet_response[0].user.profile_image_url,
+ user_name:tweet_response[0].user.name,
+ tweet_text:tweet_response[0].text
+ }))
+}
+
+var show_panel = function(identifier) {
+ x$(".twt_panel").css({display:'none'});
+ x$(identifier).css({display:'block'});
+}
+
+var load_local_tweets = function(container_id) {
+ var suc = function(p) {
+ var params = "geocode=" + encodeURIComponent(p.latitude + "," + p.longitude + ",25km");
+ var query_url = tweet_search_url + "?" + params;
+ x$(container_id).xhr(query_url,
+ { callback: function() {
+ var tweetstream = eval("[" + this.responseText + "]")[0].results;
+ x$.data.new_tweets = tweetstream;
+ setTimeout("display_search_tweets(x$.data.new_tweets,'"+container_id+"')",10);
+ },
+ method: "get"
+ });
+ };
+ var fail = function(){
+ alert("failed");
+ };
+ navigator.geolocation.getCurrentPosition(suc,fail);
+}
+
+var search_tweets = function(container_id, search_query) {
+ var params = "q=" + encodeURIComponent(search_query);
+ var query_url = tweet_search_url + "?" + params;
+ x$(container_id).xhr(query_url,
+ { callback: function() {
+ var tweetstream = eval("[" + this.responseText + "]")[0].results;
+ x$.data.new_tweets = tweetstream;
+ display_search_tweets(x$.data.new_tweets,container_id);
+ },
+ method: "get"
+ });
+}
+
+var display_search_tweets = function(tweetstream,container_id) {
+ x$(container_id + " div").remove();
+ var i=0;
+ for (i=0; i<tweetstream.length; i++) {
+ var div_c = format_tweet({profile_image:tweetstream[i].profile_image_url,
+ user_name:tweetstream[i].from_user,tweet_text:tweetstream[i].text });
+ x$(container_id).html("bottom",div_c);
+ }
+}
+
+var login_function = function(e) {
+ document.getElementById('user_field').blur();
+ document.getElementById('pass_field').blur();
+
+ x$.data.m_user = x$("#user_field").elements[0].value;
+ x$.data.m_pass = x$("#pass_field").elements[0].value;
+
+ sql.post("user",x$.data.m_user);
+ sql.post("password",x$.data.m_pass);
+
+ load_tweets("#content",x$.data.m_user,x$.data.m_pass);
+ show_panel("#content"); // failing?
+ x$(".panel").css({display:'none'}); // failing?
+ x$("#post_new_tweet").css({display:"block"});
+ e.preventDefault();
+}
+
+var search_function = function(e) {
+ document.getElementById('query').blur();
+
+ var search_query = document.getElementById('query').value;
+ x$("#search_term").html(search_query);
+ search_tweets("#search_results",search_query);
+ show_panel("#search_panel");
+
+ e.preventDefault();
+}
View
87 android/assets/www/script/sql.js
@@ -0,0 +1,87 @@
+/**
+* XUI SQL
+* ---
+*
+* RESTFUL (like) SQL Lite Wrapper for Storing Data - Key Value Pair
+*/
+
+var sql = function() {
+ var dbName = 'storeDB';
+ var version = '1.0';
+ var dbTable = 'storeDBTbl';
+ var displayName = 'STORE-SQL';
+ var maxSize = 65536;
+ var db = null;
+
+ var defaultErrorHandle = function(tx,error){ console.log(error.message); }
+ var defaultDataHandle = function(result){ console.log(result); }
+
+ var now = function() { return new Date().getTime(); }
+
+ return {
+ setup: function(){
+ var setupTable = function(tx,error) {
+ tx.executeSql("CREATE TABLE "+ dbTable + " (key NVARCHAR(32) UNIQUE, value TEXT, timestamp REAL)", [], function(result) {}, defaultErrorHandle);
+ }
+
+ if (window.openDatabase) {
+ db = openDatabase(dbName, version, displayName, maxSize);
+ db.transaction(function(tx) {
+ tx.executeSql("SELECT COUNT(*) FROM " + dbTable , [], function(){}, setupTable
+ )});
+
+ } else {
+ console.log("Error Could not create DB either the DB has exceeded its size limit or you are using the wrong browser.");
+ }
+
+ return this;
+ },
+
+ // alias for SELECT
+ get: function(key,fnc) {
+ if (typeof fnc != 'function') return;
+ db.transaction(function(tx) {
+ tx.executeSql("SELECT value FROM " + dbTable + " WHERE key = ?",[key],function(tx,results) {
+ if (results.rows.length == 1) {
+ fnc(results.rows.item(0).value);
+ } else {
+ fnc(null);
+ }
+ }, defaultErrorHandle);
+ });
+ },
+
+ // alias for INSERT
+ post: function(key, value){
+ db.transaction(function(tx) {
+ tx.executeSql("INSERT INTO " + dbTable + " (key,value,timestamp) VALUES (?,?,?)",[key,value,now()],defaultDataHandle,defaultErrorHandle);
+ });
+ },
+
+ // alias for DELETE JavaScript 'delete' is a reserved word
+ del: function(key){
+ db.transaction(function(tx) {
+ tx.executeSql("DELETE FROM " + dbTable + " WHERE key = ? ",[key], defaultDataHandle,defaultErrorHandle);
+ });
+ },
+
+ // alias for UPDATE
+ put: function(key, value){
+ db.transaction(function(tx) {
+ tx.executeSql("UPDATE " + dbTable + " SET value=?,timestamp=? WHERE key=? ",[value,now(),key],defaultDataHandle,defaultErrorHandle);
+ });
+ },
+
+ exists: function(key,fnc){
+ this.get(key,function(d){
+ fnc((d == null) ? false : true);
+ });
+ },
+
+ clear: function(){
+ db.transaction(function(tx) {
+ tx.executeSql("DELETE FROM " + dbTable ,[],defaultDataHandle,defaultErrorHandle);
+ });
+ }
+ }
+}().setup();
View
1  android/assets/www/script/xui-min.js
@@ -0,0 +1 @@
+(function(){var _$=function(q){q=q||document;return this.find(q)};_$.extend=function(obj){var original=this.prototype;var extended=obj;for(var key in (extended||{})){original[key]=extended[key]}return original};_$.prototype={elements:[],find:function(q){var ele=[];var qlen=q.length;for(var i=0;i<qlen;i++){if(typeof q[i]=="string"){var list=document.querySelectorAll(q[i]);var size=list.length;for(var j=0;j<size;j++){ele.push(list[j])}}else{if(q[i] instanceof Array){for(var x=0;x<q[i].length;x++){var list=document.querySelectorAll(q[i][x]);var size=list.length;for(var j=0;j<size;j++){ele.push(list[j])}}}else{ele.push(q[i])}}}this.elements=this.elements.concat(this.reduce(ele));return this},reduce:function(el,b){var a=[],i,l=el.length;for(i=0;i<l;i++){if(a.indexOf(el[i],0,b)<0){a.push(el[i])}}return a},removex:function(array,from,to){var rest=array.slice((to||from)+1||array.length);array.length=from<0?array.length+from:from;return array.push.apply(array,rest)},has:function(q){var t=[];this.each(function(el){x$(q).each(function(hel){if(hel==el){t.push(el)}})});this.elements=t;return this},not:function(q){var list=this.elements;for(var i=0;i<list.length;i++){x$(q).each(function(hel){if(list[i]==hel){this.elements=this.removex(list,list.indexOf(list[i]))}})}return this},add:function(q){this.find([q]);this.elements=this.reduce(this.elements);return this},first:function(){return this.elements[0]},each:function(fn){for(var i=0,len=this.elements.length;i<len;++i){fn.call(this,this.elements[i])}return this}};var Dom={inner:function(html){return this.html("inner",html)},outer:function(html){return this.html("outer",html)},top:function(html){return this.html("top",html)},bottom:function(html){return this.html("bottom",html)},remove:function(){return this.html("remove")},html:function(location,html){var getTag=function(el){if(el.firstChild==null){switch(el.tagName){case"UL":return"LI";break;case"DL":return"DT";break;case"TR":return"TD";break;default:return el.tagName}}return el.firstChild.tagName};var wrap=function(xhtml,tag){var attributes={};var re=/^<([A-Z][A-Z0-9]*)([^>]*)>(.*)<\/\1>/i;if(re.test(xhtml)){result=re.exec(xhtml);tag=result[1];if(result[2]!=""){var attrList=result[2].split(/([A-Z]*\s*=\s*['|"][A-Z0-9:;#\s]*['|"])/i);for(var i=0;i<attrList.length;i++){var attr=attrList[i].replace(/^\s*|\s*$/g,"");if(attr!=""&&attr!=" "){var node=attr.split("=");attributes[node[0]];attributes[node[0]]=node[1].replace(/(["']?)/g,"")}}}xhtml=result[3]}var element=document.createElement(tag);for(var x in attributes){var a=document.createAttribute(x);a.nodeValue=attributes[x];element.setAttributeNode(a)}element.innerHTML=xhtml;return element};this.clean();if(arguments.length==1&&arguments[0]!="remove"){html=location;location="inner"}this.each(function(el){switch(location){case"inner":if(typeof html=="string"){el.innerHTML=html;var list=el.getElementsByTagName("SCRIPT");var len=list.length;for(var i=0;i<len;i++){eval(list[i].text)}}else{el.innerHTML="";el.appendChild(html)}break;case"outer":if(typeof html=="string"){html=wrap(html,getTag(el))}el.parentNode.replaceChild(html,el);break;case"top":if(typeof html=="string"){html=wrap(html,getTag(el))}el.insertBefore(html,el.firstChild);break;case"bottom":if(typeof html=="string"){html=wrap(html,getTag(el))}el.insertBefore(html,null);break;case"remove":var parent=el.parentNode;parent.removeChild(el);break}});return this},clean:function(){var ns=/\S/;this.each(function(el){var d=el,n=d.firstChild,ni=-1;while(n){var nx=n.nextSibling;if(n.nodeType==3&&!ns.test(n.nodeValue)){d.removeChild(n)}else{n.nodeIndex=++ni}n=nx}});return this}};var Event={click:function(fn){return this.on("click",fn)},load:function(fn){return this.on("load",fn)},touchstart:function(fn){return this.on("touchstart",fn)},touchmove:function(fn){return this.on("touchmove",fn)},touchend:function(fn){return this.on("touchend",fn)},touchcancel:function(fn){return this.on("touchcancel",fn)},gesturestart:function(fn){return this.on("gesturestart",fn)},gesturechange:function(fn){return this.on("gesturechange",fn)},gestureend:function(fn){return this.on("gestureend",fn)},orientationchange:function(fn){return this.on("orientationchange",fn)},on:function(type,fn){var listen=function(el){if(window.addEventListener){el.addEventListener(type,fn,false)}};this.each(function(el){listen(el)});return this}};var Style={setStyle:function(prop,val){this.each(function(el){el.style[prop]=val});return this},getStyle:function(prop,callback){var gs=function(el,p){return document.defaultView.getComputedStyle(el,"").getPropertyValue(p)};if(callback==undefined){return gs(this.first(),prop)}this.each(function(el){callback(gs(el,prop))});return this},addClass:function(className){var that=this;var hasClass=function(el,className){var re=that.getClassRegEx(className);return re.test(el.className)};this.each(function(el){if(hasClass(el,className)==false){el.className+=" "+className}});return this},removeClass:function(className){if(className==undefined){this.each(function(el){el.className=""})}else{var re=this.getClassRegEx(className);this.each(function(el){el.className=el.className.replace(re," ")})}return this},css:function(o){var that=this;this.each(function(el){for(var prop in o){that.setStyle(prop,o[prop])}});return this||that},reClassNameCache:{},getClassRegEx:function(className){var re=this.reClassNameCache[className];if(!re){re=new RegExp("(?:^|\\s+)"+className+"(?:\\s+|$)");this.reClassNameCache[className]=re}return re}};var Fx={tween:function(options){if(options instanceof Array){for(var i=0;i<options.length;i++){this.animationStack.push(options[i])}}else{if(options instanceof Object){this.animationStack.push(options)}}this.start();return this},animationStack:[],start:function(){var t=0;for(var i=0;i<this.animationStack.length;i++){var options=this.animationStack[i];var duration=options.duration==undefined?0.5:options.duration;setTimeout(function(s,o){s.animate(o)},t*1000*duration,this,options);t+=duration}return this},animate:function(options){var that=this;var opt_after=options.after;var easing=(options.easing==undefined)?"ease-in":options.easing;var before=(options.before==undefined)?function(){}:options.before;var after=(opt_after==undefined)?function(){}:function(){opt_after.apply(that)};var duration=(options.duration==undefined)?0.5:options.duration;var translate=options.by;var rotate=options.rotate;options.easing=options.rotate=options.by=options.before=options.after=options.duration=undefined;before.apply(before.arguments);this.setStyle("-webkit-transition","all "+duration+"s "+easing);this.each(function(el){for(var prop in options){that.setStyle(prop,options[prop])}if(translate){that.setStyle("-webkit-transform",that.translateOp(translate[0],translate[1]))}});setTimeout(function(){that.setStyle("-webkit-transition","none")},duration*1000);setTimeout(function(){that.setStyle("-webkit-transform","none")},duration*1000);setTimeout(after,duration*1000);return this||that},translateOp:function(xPixels,yPixels){return"translate("+xPixels+"px, "+yPixels+"px)"},rotateOp:function(axis,degree){return"rotate"+axis+"("+degree+"deg)"}};var Xhr={xhr:function(url,options){if(options==undefined){var options={}}var that=this;var req=new XMLHttpRequest();var method=options.method||"get";var async=options.async||false;var params=options.data||null;req.open(method,url,async);if(options.headers){var i=0;for(i=0;i<options.headers.length;i++){req.setRequestHeader(options.headers[i].name,options.headers[i].value)}}req.onload=(options.callback!=null)?options.callback:function(){that.html(this.responseText)};req.send(params);return this},xhrjson:function(url,options){if(options==undefined){return this}var that=this;var cb=options.callback;if(typeof cb!="function"){cb=function(x){return x}}var callback=function(){var o=eval("("+this.responseText+")");for(var prop in o){x$(options.map[prop]).html(cb(o[prop]))}};options.callback=callback;this.xhr(url,options);return this}};var libs=[Dom,Event,Style,Fx,Xhr];for(var i=0,size=libs.length;i<size;i++){_$.extend(libs[i])}var xui=window.x$=function(){return new _$(arguments)}})();
View
BIN  android/bin/Pigeon.apk
Binary file not shown
View
BIN  android/bin/classes.dex
Binary file not shown
View
BIN  android/bin/com/pigeon/app/AccelListener.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/AccelTuple.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/AudioHandler$1.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/AudioHandler.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/CameraLauncher.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/CameraPreview$1.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/CameraPreview$2.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/CameraPreview$3.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/CameraPreview.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/CompassListener.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/DirectoryManager.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/DroidGap$GapClient.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/DroidGap.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/FileUtils.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/GeoBroker.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/GeoListener.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/GeoTuple.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/GpsListener.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/HttpHandler.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/NetworkListener.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/Orientation.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/PhoneGap.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/R$attr.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/R$drawable.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/R$id.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/R$layout.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/R$raw.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/R$string.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/R.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/SmsListener.class
Binary file not shown
View
BIN  android/bin/com/pigeon/app/VideoPreview.class
Binary file not shown
View
BIN  android/bin/resources.ap_
Binary file not shown
View
61 android/build.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Pigeon">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contain the path to the SDK. It should *NOT* be checked in in Version
+ Control Systems. -->
+ <property file="local.properties"/>
+
+ <!-- The build.properties file can be created by you and is never touched
+ by the 'android' tool. This is the place to change some of the default property values
+ used by the Ant rules.
+ Here are some properties you may want to change/update:
+
+ application-package
+ the name of your application package as defined in the manifest. Used by the
+ 'uninstall' rule.
+ source-folder
+ the name of the source folder. Default is 'src'.
+ out-folder
+ the name of the output folder. Default is 'bin'.
+
+ Properties related to the SDK location or the project target should be updated
+ using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your application and
+ should be checked in in Version Control Systems.
+
+ -->
+ <property file="build.properties"/>
+
+ <!-- The default.properties file is created and updated by the 'android' tool, as well
+ as ADT.
+ This file is an integral part of the build system for your application and
+ should be checked in in Version Control Systems. -->
+ <property file="default.properties"/>
+
+ <!-- Custom Android task to deal with the project target, and import the proper rules.
+ This requires ant 1.6.0 or above. -->
+ <path id="android.antlibs">
+ <pathelement path="${sdk-location}/tools/lib/anttasks.jar" />
+ <pathelement path="${sdk-location}/tools/lib/sdklib.jar" />
+ <pathelement path="${sdk-location}/tools/lib/androidprefs.jar" />
+ <pathelement path="${sdk-location}/tools/lib/apkbuilder.jar" />
+ <pathelement path="${sdk-location}/tools/lib/jarutils.jar" />
+ </path>
+
+ <taskdef name="setup"
+ classname="com.android.ant.SetupTask"
+ classpathref="android.antlibs"/>
+
+ <!-- Execute the Android Setup task that will setup some properties specific to the target,
+ and import the rules files.
+ To customize the rules, copy/paste them below the task, and disable import by setting
+ the import attribute to false:
+ <setup import="false" />
+
+ This will ensure that the properties are setup correctly but that your customized
+ targets are used.
+ -->
+ <setup />
+</project>
View
14 android/default.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+apk-configurations=
+# Project target.
+target=Google Inc.:Google APIs:4
+# Indicates whether an apk should be generated for each density.
+split.density=false
View
35 android/gen/com/pigeon/app/R.java
@@ -0,0 +1,35 @@
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+
+package com.pigeon.app;
+
+public final class R {
+ public static final class attr {
+ }
+ public static final class drawable {
+ public static final int icon=0x7f020000;
+ }
+ public static final class id {
+ public static final int appView=0x7f060000;
+ public static final int go=0x7f060002;
+ public static final int surface=0x7f060001;
+ }
+ public static final class layout {
+ public static final int main=0x7f030000;
+ public static final int preview=0x7f030001;
+ }
+ public static final class raw {
+ public static final int bird=0x7f040000;
+ public static final int off=0x7f040001;
+ public static final int on=0x7f040002;
+ }
+ public static final class string {
+ public static final int app_name=0x7f050000;
+ public static final int go=0x7f050002;
+ public static final int url=0x7f050001;
+ }
+}
View
BIN  android/libs/commons-codec-1.3.jar
Binary file not shown
View
BIN  android/res/drawable/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
11 android/res/layout/main.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <WebView android:id="@+id/appView"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ />
+</LinearLayout>
View
23 android/res/layout/preview.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:orientation="horizontal">
+ <SurfaceView android:id="@+id/surface"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:layout_weight="1">
+ </SurfaceView>
+ <Button
+ android:id="@+id/go"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+
+ android:text="@string/go"
+ android:minWidth="50dip"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginRight="5dip"
+ android:layout_marginTop="5dip"
+ />
+
+</RelativeLayout>
View
BIN  android/res/raw/bird.mp3
Binary file not shown
View
BIN  android/res/raw/off.mp3
Binary file not shown
View
BIN  android/res/raw/on.mp3
Binary file not shown
View
6 android/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">Pigeon</string>
+ <string name="url">file:///android_asset/www/index.html</string>
+ <string name="go">Snap</string>
+</resources>
View
68 android/src/com/pigeon/app/AccelListener.java
@@ -0,0 +1,68 @@
+package com.pigeon.app;
+
+import static android.hardware.SensorManager.DATA_X;
+import static android.hardware.SensorManager.DATA_Y;
+import static android.hardware.SensorManager.DATA_Z;
+import android.hardware.SensorManager;
+import android.content.Context;
+import android.hardware.SensorListener;
+import android.webkit.WebView;
+
+@SuppressWarnings("deprecation")
+public class AccelListener implements SensorListener{
+
+ WebView mAppView;
+ Context mCtx;
+ String mKey;
+ int mTime = 10000;
+ boolean started = false;
+
+ private SensorManager sensorManager;
+
+ private long lastUpdate = -1;
+
+ AccelListener(Context ctx, WebView appView)
+ {
+ mCtx = ctx;
+ mAppView = appView;
+ sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE);
+ }
+
+ public void start(int time)
+ {
+ mTime = time;
+ if (!started)
+ {
+ sensorManager.registerListener(this,
+ SensorManager.SENSOR_ACCELEROMETER,
+ SensorManager.SENSOR_DELAY_GAME);
+ }
+ }
+