Compare commits

..

83 Commits

Author SHA1 Message Date
Joe Bowser
e55cef9c14 Fixing accel 2010-06-04 13:25:28 -07:00
Joe Bowser
c1e628f44c Fixing up the accelerometer. Weird issue with where zero is 2010-06-04 11:42:12 -07:00
Joe Bowser
cd5788c3ce Merge branch 'master' of git@github.com:phonegap/phonegap-android into accel_hack 2010-05-31 11:37:41 -07:00
Joe Bowser
5c8e029da1 Updating to 2.2 2010-05-31 10:59:44 -07:00
Igor Anic
a65b578449 adding useful telephony information to Device; sim serial number and some oters
(cherry picked from commit da8c4f4a7539b2e6165d48ad6859f65c3133fc59)
2010-05-14 16:24:30 -07:00
Igor Anic
7506548ae2 little better database quota management, increse db size in steps of 1Mb
(cherry picked from commit f5cd1fe73d6cd24ad48b36def86ead5a1f5141ea)
2010-05-14 16:24:19 -07:00
Igor Anic
dfe0b6ff27 console.log for api level 7
(cherry picked from commit a2b08f305b33de38c1ffa93f2a13ed4636482bc1)
2010-05-14 16:23:32 -07:00
Joe Bowser
a179fbd095 Attempt to fix the HTML 5 storage 2010-05-14 15:49:14 -07:00
Joe Bowser
9c1a1207bb Merge branch 'master' of http://github.com/stevengill/phonegap-android 2010-05-10 16:10:04 -07:00
Steven Gill
4ff406f9df fixed geolocation null bug 2010-05-06 15:43:56 -07:00
Joe Bowser
64671184a6 Initial Commit - Fixing Accelerometer 2010-04-28 15:46:15 -07:00
Joe Bowser
36e90c9e22 Adding sms:// to DroidGap, not quite working, since it doesn't pre-populate the number 2010-04-26 10:44:13 -07:00
Joe Bowser
2f6a9e18d0 Adding a WebViewClient with verbose checking 2010-04-23 16:18:11 -07:00
Joe Bowser
ceabaf1e37 Fixing the WebViewClient so we view pages in PhoneGap 2010-04-23 15:08:15 -07:00
filmaj
020178e40b Merged Joe`s turning off of native geolocation in WebView. 2010-03-31 14:02:08 -07:00
Joe Bowser
69e580136a Forgot the min SDK is 2, not 3 2010-03-30 12:02:08 -07:00
Joe Bowser
72fd058b9e Turning off the Native WebKit Geolcation 2010-03-29 16:56:07 -07:00
Joe Bowser
827c0ec81f Removing junk Orientation class 2010-03-26 15:34:29 -07:00
filmaj
887ab4a28b Added explicit disabling of native Geolocation object in the web client, added a fallback measure to JavaScript geolocation PhoneGap constructor so that it builds/proxies the the instantiated Geo objects properly if it still does exist. 2010-03-23 16:37:30 -07:00
filmaj
655c6ac130 Merge branch 'master' of github.com:phonegap/phonegap-android 2010-03-19 16:47:24 -07:00
Brock Whitten
87dd64d36c Adding LICENSE file 2010-03-17 15:19:59 -07:00
filmaj
24d5948d0d Minor changes to droidgap to make it work on my shell (cygwin), merging in Joe`s changes/fixes to geo + JavaScript 2010-03-17 11:02:10 -07:00
filmaj
f53b4ec109 Merged imhotep`s changes, still need to fix droidgap and the android shell call on Windows vs. other OSes. 2010-03-17 10:50:43 -07:00
Anis
915bf19378 Merge branch 'master' of github.com:imhotep/phonegap-android 2010-03-15 17:44:44 -07:00
Anis
a4cc222a43 fixing some minor js issue 2010-03-15 17:38:46 -07:00
Brock Whitten
fade602c0b Merge branch 'master' of github.com:phonegap/phonegap-android 2010-03-15 17:01:27 -07:00
Brock Whitten
f32bb7057e Fixed ridiculous error in Javascript for GeoLocation 2010-03-15 17:01:12 -07:00
Brock Whitten
57a41b7b2f Found syntax error in Geolocation. Probably been lurking here for months 2010-03-15 16:07:14 -07:00
Brock Whitten
db03ff397f Fixing stuff 2010-03-15 15:32:12 -07:00
filmaj
52a49aaaea Fixed droidgap to handle spaces in SDK directory. 2010-03-11 16:11:39 -08:00
filmaj
941d6805ec Adding newly-built phonegap.js to repo post-build. 2010-03-04 15:14:40 -08:00
filmaj
bdf01735cd Merging. 2010-03-04 15:11:49 -08:00
Brock Whitten
c750109bd7 Fixes to make it work with the cancer that is Android 1.5 2010-03-03 17:07:15 -08:00
Brock Whitten
6b269b85d2 Adding 2.1 DOM Storage 2010-03-02 11:14:20 -08:00
Brock Whitten
1d4a67cdad Adding console.log capability to PhoneGap 2010-02-26 11:25:28 -08:00
Brock Whitten
64574be133 Can't get the disk space until we get the disk space 2010-02-25 11:45:57 -08:00
Brock Whitten
be5c31ee1c Fixed pathing issues. Calls it absolutely now based on PhoneGap SDK 2010-02-25 10:28:16 -08:00
Brock Whitten
c3c5d522a3 Adding the tutorial to the project 2010-02-25 10:12:31 -08:00
Brock Whitten
f93c2badcc Minor change for synchronous write. This seems like a bad idea. 2010-02-25 10:09:58 -08:00
Brock Whitten
9c0259c2c1 Changing File Behaviour to sync with iPhone 2010-02-25 09:46:46 -08:00
Brock Whitten
2fa78679cb Adding Javascript Interface for Crypto 2010-02-24 16:19:01 -08:00
Brock Whitten
cb90852dfc Adding Built-In Crypto Library 2010-02-24 16:18:35 -08:00
Brock Whitten
c4ac7e5383 Merge branch 'master' of git://github.com/brianleroux/phonegap-android 2010-02-24 16:00:36 -08:00
Brock Whitten
693cb4695f Fixed a null error on NetworkManager 2010-02-24 15:43:00 -08:00
filmaj
73b18de56f Tweaked status message. 2010-02-24 15:42:49 -08:00
filmaj
fcce200701 More weird merge bs. 2010-02-24 15:42:23 -08:00
filmaj
de8dc4af2a Merging droidgap changes from LeRoux. 2010-02-24 15:36:07 -08:00
Brian LeRoux
466c7ccaff some cleanup of droidgap 2010-02-24 15:23:33 -08:00
Brian LeRoux
fa2776d3d7 merge of inaseer cleanup 2010-02-24 15:06:44 -08:00
Brian LeRoux
17d4d521e7 minor edits 2010-02-24 15:00:03 -08:00
ARenzi
c8bfbab522 I am using the inline editor (github) and i forgot a "type =" before info.getTypeName();
:)
ARenzi
2010-02-23 14:51:56 -07:00
filmaj
32e8ecc772 Oops forgot semi-colon. 2010-02-23 11:42:41 -08:00
filmaj
02c750134c Added ARenzi`s Reachability fixes. 2010-02-23 11:07:30 -08:00
Fil Maj
b0054aa1b4 Merge branch 'master' of git@github.com:phonegap/phonegap-android 2010-02-19 10:15:45 -08:00
Immad Naseer
594e77690c droidgap parses the output of android list targets to find the id for 'android-5' or defaults to 5 if it can't find the id in the output 2010-02-17 15:31:40 -08:00
Immad Naseer
37c3c2528d Refactored the code dealing w/ file/directory manipulation.
- The code makes sure the target directory structure exists before copying files.
  - Minimized usage of Dir.chdir
  - Cleaned up the code dealing w/ cross-platform file paths.
2010-02-16 15:22:42 -08:00
Immad Naseer
10d455d560 Changing the tabs in droidgap to spaces 2010-02-16 14:59:22 -08:00
Immad Naseer
7820451108 small string concatenation performance optimization 2010-02-16 14:34:50 -08:00
Brock Whitten
3d91a98b3a Fixing up StandAlone for debugging purposes 2010-02-16 12:11:43 -08:00
Brock Whitten
c638fbfa69 Fixing nulls 2010-02-16 10:28:07 -08:00
Brock Whitten
17528c15bb Merge branch 'master' of github.com:phonegap/phonegap-android 2010-02-15 14:00:25 -08:00
Brian LeRoux
f491a69769 Merge branch 'master' of git://github.com/filmaj/phonegap-android 2010-02-14 23:41:20 -08:00
Brian LeRoux
bf01ba0aea whatever small changes 2010-02-14 23:40:35 -08:00
filmaj
76a8203176 Fixed small contacts and accelerometer object instantiation bugs. Added a bit more delay to PhoneGap constructor, 1ms caused issues sometimes I *think*. 2010-02-13 18:58:45 -08:00
filmaj
5255f63237 Fixed building of phonegap.js in build script. Fixed GPS on Android 2.0+ - I guess they updated the version of WebKit being used on Android (similar now to how it works on iPhone) and thus the browser has a native navigator.geolocation object. Employed Jesses approach to proxying an objects method since we can`t directly overwrite it. 2010-02-13 17:09:02 -08:00
filmaj
0c585b7416 Added JS concatenation and copy over to assets/www to build script. 2010-02-13 15:01:10 -08:00
filmaj
edd0a2caf6 Updated build file after mergin in thorstens changes. 2010-02-10 13:09:39 -08:00
filmaj
91c4174f19 Merging build script... 2010-02-10 12:44:32 -08:00
Thorsten Rinne
3862632af1 Fixed paths and project generation 2010-02-10 08:19:36 +01:00
Brock Whitten
1f9571a3da Changing the simple example 2010-02-05 16:08:24 -08:00
unknown
c023c3d8cc Updated the Ruby build script so that this shiat works on Windows! 2010-02-03 16:41:39 -08:00
Brock Whitten
4c0da8e241 Fixing Build 2010-02-03 10:27:49 -08:00
Brock Whitten
e01dfec400 Hacky fix for GeoLocation on the 2.1 Emulator 2010-01-29 16:02:20 -08:00
Brian LeRoux
cf70f7d4a7 being picky about md formatting 2010-01-27 15:14:49 -08:00
Brian LeRoux
4934877515 fix for the readme 2010-01-27 15:13:26 -08:00
Brian LeRoux
c3cd44c04c updated readme to reflect change to build process 2010-01-27 15:11:25 -08:00
Brian LeRoux
bb7b973bf0 sweet one line building! 2010-01-27 15:00:21 -08:00
Brian LeRoux
816341030f generating apps works; needs to build js from assets 2010-01-26 17:58:27 -08:00
Brian LeRoux
923c29aa2b cleanup continued 2010-01-26 16:24:35 -08:00
Brian LeRoux
e3dc010b97 reorg of project assets 2010-01-26 13:54:02 -08:00
Brian LeRoux
fc6f2f5d39 removes and .gitignore framework/local.properties, updated README 2010-01-25 22:03:19 -08:00
unknown
4144587640 Expanded instructions in README. 2010-01-21 00:22:39 -08:00
Joe Bowser
d81f53465f Fixing the 1.5 Storage. Got inheritance wrong in this case 2010-01-04 11:53:26 -08:00
58 changed files with 1781 additions and 1160 deletions

4
.gitignore vendored
View File

@@ -1,4 +1,6 @@
default.properties
bin
gen
assets/www/phonegap.js
assets/www/phonegap.js
local.properties
framework/phonegap.jar

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) 2010 Nitobi
website: http://phonegap.com
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Software), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,33 +1,46 @@
PhoneGap Android
=============================================================
PhoneGap Android is an Android application library that allows
for PhoneGap based projects to be built for the Android Platform.
PhoneGap/Android
================
PhoneGap/Android is an Android application library that allows for PhoneGap based projects to be built for the Android Platform. PhoneGap based applications are, at the core, an application written with web technology: HTML, CSS and JavaScript.
Pre-requisites
-------------------------------------------------------------
* Java JDK 1.5
* Android SDK Package [http://developer.android.com](http://developer.android.com)
* Apache ANT (For build script)
--------------
- Java JDK 1.5
- Android SDK Package [http://developer.android.com](http://developer.android.com)
- Apache ANT
- Ruby
Recommended:
----------------------------------------------------------------
* Ruby, Rubygems (for build.rb)
* Eclipse (Recommended for back-end debugging, not required)
Recommended
-----------
- Eclipse (Great for debugging and extending PhoneGap/Android with your own Java plugins.)
Getting Started from Command Line
Getting Started with PhoneGap/Android
--------------------------------------
Step 1: cd framework && ant jar
Step 2: In the root directory, run:
ruby build.rb <app-name> <package_name> <wwwdir> <path>
1. From the root of this repo run the following command to generate a new PhoneGap/Android app:
app-name: Name of application without spaces
package name: Java namespace of package ( i.e. com.nitobi.demo)
www-dir: www directory which includes an icon.png file for the icon
path: The path you wish to put your PhoneGap Application
<pre>
./droidgap [android_sdk_path] [name] [package_name] [www] [path]
Using Eclipse with PhoneGap
-------------------------------------------------------------
The wiki article to get started with Eclipse can be found at [http://phonegap.pbworks.com/Getting-started-with-Android-PhoneGap-in-Eclipse](http://phonegap.pbworks.com/Getting-started-with-Android-PhoneGap-in-Eclipse)
android_sdk_path ... The path to your Android SDK install.
name ............... The name of your application.
package_name ....... The name of your package (For example: com.nitobi.demo)
www ................ The path to your www folder. (Wherein your HTML, CSS and JS app is.)
path ............... The path to generate the application.
</pre>
Thats it!
Importing a PhoneGap/Android app into Eclipse
---------------------------------------------
1. File > New > Project...
2. Android > Android Project
3. Create project from existing source (point to the generated app). This should import the project into Eclipse. Almost done!
4. Right click on libs/phonegap.jar and add to build path.
5. Right click on the project root: Run as > Run Configurations
6. Click on the Target tab and select Manual (this way you can choose the emulator or device to build to).
For more info see
-----------------
- [http://docs.phonegap.com](http://docs.phonegap.com)
- [http://wiki.phonegap.com](http://wiki.phonegap.com)

147
assets/www/index.html Normal file
View File

@@ -0,0 +1,147 @@
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=320; user-scalable=no" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>PhoneGap</title>
<link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8">
<script type="text/javascript" charset="utf-8" src="phonegap.js"></script>
<script type="text/javascript" charset="utf-8">
var deviceInfo = function(){
document.getElementById("platform").innerHTML = device.platform;
document.getElementById("version").innerHTML = device.version;
document.getElementById("uuid").innerHTML = device.uuid;
console.log("Height:" + window.innerHeight);
console.log("Width:" + window.innerWidth);
}
var getLocation = function() {
var suc = function(p){
alert(p.coords.latitude + " " + p.coords.longitude);
};
var fail = function(){};
navigator.geolocation.getCurrentPosition(suc,fail);
}
var beep = function(){
navigator.notification.beep(2);
}
var vibrate = function(){
navigator.notification.vibrate(0);
}
var getContact = function(){
var suc = function(c){ alert("Contact 4: " + c.contacts[3].name); };
var fail = function(){};
navigator.ContactManager.get(suc, fail);
}
var watchAccel = function() {
var suc = function(a){
document.getElementById('x').innerHTML = roundNumber(a.x);
document.getElementById('y').innerHTML = roundNumber(a.y);
document.getElementById('z').innerHTML = roundNumber(a.z);
};
var fail = function(){};
var opt = {};
opt.frequency = 100;
timer = navigator.accelerometer.watchAcceleration(suc,fail,opt);
}
function roundNumber(num) {
var dec = 3;
var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
return result;
}
var preventBehavior = function(e) {
e.preventDefault();
};
function show_pic()
{
var viewport = document.getElementById('viewport');
viewport.style.display = "";
navigator.camera.getPicture(dump_pic, fail, { quality: 50 });
}
function dump_pic(data)
{
var viewport = document.getElementById('viewport');
console.log(data);
viewport.style.display = "";
viewport.style.position = "absolute";
viewport.style.top = "10px";
viewport.style.left = "10px";
document.getElementById("test_img").src = "data:image/jpeg;base64," + data;
}
function close()
{
var viewport = document.getElementById('viewport');
viewport.style.position = "relative";
viewport.style.display = "none";
}
function fail(fail)
{
alert(fail);
}
// This is just to do this.
function readFile()
{
navigator.file.read('/sdcard/phonegap.txt', fail , fail);
}
function writeFile()
{
navigator.file.write('foo.txt', "This is a test of writing to a file", fail, fail);
}
function get_contacts()
{
navigator.ContactManager.getAllContacts(count_contacts, fail, null);
}
function count_contacts(contacts)
{
alert(contacts.length);
}
function init(){
document.addEventListener("touchmove", preventBehavior, false);
document.addEventListener("deviceready", deviceInfo, true);
}
</script>
</head>
<body onload="init();" id="stage" class="theme">
<h1>Welcome to PhoneGap!</h1>
<h2>this file is located at assets/index.html</h2>
<div id="info">
<h4>Platform: <span id="platform">&nbsp;</span></h4>
<h4>Version: <span id="version">&nbsp;</span></h4>
<h4>UUID: <span id="uuid">&nbsp;</span></h4>
</div>
<dl id="accel-data">
<dt>X:</dt><dd id="x">&nbsp;</dd>
<dt>Y:</dt><dd id="y">&nbsp;</dd>
<dt>Z:</dt><dd id="z">&nbsp;</dd>
</dl>
<a href="#" class="btn large" onclick="watchAccel();">Watch Accelerometer</a>
<a href="#" class="btn large" onclick="getLocation();">Get Location</a>
<a href="tel://411" class="btn large">Call 411</a>
<a href="#" class="btn large" onclick="beep();">Beep</a>
<a href="#" class="btn large" onclick="vibrate();">Vibrate</a>
<a href="#" class="btn large" onclick="show_pic();">Get a Picture</a>
<a href="#" class="btn large" onclick="get_contacts();">Get phone's contacts</a>
<div id="viewport" class="viewport" style="display: none;">
<img style="width:60px;height:60px" id="test_img" src="" />
</div>
</body>
</html>

View File

@@ -1,80 +0,0 @@
require 'rubygems'
require 'nokogiri'
require 'fileutils'
class Build
attr_reader :path
attr_reader :name
attr_reader :package_name
attr_reader :www_dir
def start(name, pkg_name, www, path)
create_android(name, pkg_name, path)
@www_dir = www
generate_manifest
copy_libs
write_java
end
def create_android(name, pkg_name, path)
@name = name
@pkg_name = pkg_name
@path = path
`android create project -t 5 -k #{pkg_name} -a #{name} -n #{name} -p #{path}`
end
def generate_manifest
f = File.open('framework/AndroidManifest.xml', 'r')
doc = Nokogiri::XML(f.read)
manifest = doc.search('//manifest')
manifest[0]['package'] = @pkg_name
actions = doc.search('//activity')
actions[0]['android:name'] = ".#{@name}"
actions[1]['android:name'] = "com.phonegap.CameraPreview"
f = File.open("#{@path}/AndroidManifest.xml", 'w')
f.write(doc.to_xml)
end
def copy_libs
FileUtils.cp('framework/phonegap.jar', "#{@path}/libs")
FileUtils.cp('framework/res/values/strings.xml', "#{@path}/res/values/strings.xml")
FileUtils.mkdir_p("#{@path}/res/drawable/")
FileUtils.mkdir_p("#{@path}/assets")
FileUtils.cp_r("#{@www_dir}/", "#{@path}/assets/www")
FileUtils.cp("#{@www_dir}/icon.png", "#{@path}/res/drawable/icon.png")
end
def write_java
package_path = "#{@path}/src/" + @pkg_name.gsub('.', '/')
doc = File.open("#{package_path}/#{@name}.java", 'r')
data = doc.read.split(/\n/)
result = ""
data.each do |line|
if line.include? "android.os.Bundle"
line += "\n\nimport com.phonegap.*;"
end
if line.include? "extends Activity"
line = "public class #{@name} extends DroidGap"
end
if line.include? "setContentView"
line = " super.loadUrl(\"file:///android_asset/www/index.html\");"
end
result += line + "\n"
end
doc.close
package_path = "#{@path}/src/" + @pkg_name.gsub('.', '/')
target = File.open(package_path + "/#{@name}.java", 'w')
target.write(result);
end
end
b = Build.new
if(ARGV.length >= 3)
b.start(ARGV[0], ARGV[1], ARGV[2], ARGV[3])
else
str = "Android PhoneGap Build Tool \n Usage: build <name> <package_name> <wwwdir> <path> \n name: The name of your application \n package_name: The name of your package: i.e. com.nitobi.demo \n wwwdir: The name of your Web App \n path: Location of where you want to work on your application"
puts str
end

179
droidgap Executable file
View File

@@ -0,0 +1,179 @@
#!/usr/bin/env ruby
require 'fileutils'
# ./droidgap /Users/brianleroux/Code/android-sdk-mac MyApp com.westcoastlogic example /Users/brianleroux/Desktop/MyApp
class Build
attr_reader :android_sdk_path, :name, :pkg, :www, :path
def initialize(*a)
@android_sdk_path, @name, @pkg, @www, @path = a
@android_dir = File.expand_path(File.dirname(__FILE__))
@framework_dir = File.join(@android_dir, "framework")
end
# runs the build script
def run
build_jar
create_android
include_www
generate_manifest
copy_libs
add_name_to_strings
write_java
puts "Complete!"
end
# removes local.properties and recreates based on android_sdk_path
# then generates framework/phonegap.jar
def build_jar
puts "Building the JAR..."
%w(local.properties phonegap.js phonegap.jar).each do |f|
FileUtils.rm File.join(@framework_dir, f) if File.exists? File.join(@framework_dir, f)
end
open(File.join(@framework_dir, "local.properties"), 'w') do |f|
f.puts "sdk.dir=#{ @android_sdk_path }"
end
Dir.chdir(@framework_dir)
`ant jar`
Dir.chdir(@android_dir)
end
# runs android create project
# TODO need to allow more flexible SDK targetting
# TODO validate Android SDK
# TODO fix 'android' shell call so that it works on Windows. Can't prepend android command with path to it.
def create_android
android_exec = File.join(@android_sdk_path, "tools", "android");
target_id = 5
puts "Creating Android project for target level #{ target_id }"
`android create project -t #{ target_id } -k #{ @pkg } -a #{ @name } -n #{ @name } -p #{ @path }`
end
def include_www
puts "Adding www folder to project..."
FileUtils.mkdir_p File.join(@path, "assets", "www")
FileUtils.cp_r File.join(@www, "."), File.join(@path, "assets", "www")
end
# creates an AndroidManifest.xml for the project
def generate_manifest
puts "Generating manifest..."
manifest = ""
open(File.join(@framework_dir, "AndroidManifest.xml"), 'r') do |old|
manifest = old.read
manifest.gsub! 'android:versionCode="5"', 'android:versionCode="1"'
manifest.gsub! 'package="com.phonegap"', "package=\"#{ @pkg }\""
manifest.gsub! 'android:name=".StandAlone"', "android:name=\".#{ @name }\""
manifest.gsub! 'android:minSdkVersion="5"', 'android:minSdkVersion="3"'
end
open(File.join(@path, "AndroidManifest.xml"), 'w') { |x| x.puts manifest }
end
# copies stuff from framework into the project
# TODO need to allow for www import inc icon
def copy_libs
puts "Copying over libraries and assets and creating phonegap.js..."
framework_res_dir = File.join(@framework_dir, "res")
app_res_dir = File.join(@path, "res")
FileUtils.mkdir_p File.join(@path, "libs")
FileUtils.cp File.join(@framework_dir, "phonegap.jar"), File.join(@path, "libs")
FileUtils.mkdir_p File.join(app_res_dir, "values")
FileUtils.cp File.join(framework_res_dir, "values","strings.xml"), File.join(app_res_dir, "values", "strings.xml")
FileUtils.mkdir_p File.join(app_res_dir, "layout")
%w(main.xml preview.xml).each do |f|
FileUtils.cp File.join(framework_res_dir, "layout", f), File.join(app_res_dir, "layout", f)
end
%w(drawable-hdpi drawable-ldpi drawable-mdpi).each do |e|
FileUtils.mkdir_p File.join(app_res_dir, e)
FileUtils.cp File.join(framework_res_dir, "drawable", "icon.png"), File.join(app_res_dir, e, "icon.png")
end
# concat JS and put into www folder.
js_dir = File.join(@framework_dir, "assets", "js")
phonegapjs = IO.read(File.join(js_dir, 'phonegap.js.base'))
Dir.new(js_dir).entries.each do |script|
next if script[0].chr == "." or script == "phonegap.js.base"
phonegapjs << IO.read(File.join(js_dir, script))
phonegapjs << "\n\n"
end
File.open(File.join(@path, "assets", "www", "phonegap.js"), 'w') {|f| f.write(phonegapjs) }
end
# puts app name in strings
def add_name_to_strings
puts "Adding some application name to strings.xml..."
x = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<resources>
<string name=\"app_name\">#{ @name }</string>
<string name=\"go\">Snap</string>
</resources>
"
open(File.join(@path, "res", "values", "strings.xml"), 'w') do |f|
f.puts x.gsub(' ','')
end
end
# this is so fucking unholy yet oddly beautiful
# not sure if I should thank Ruby or apologize for this abusive use of string interpolation
def write_java
puts "Writing application Java code..."
j = "
package #{ @pkg };
import android.app.Activity;
import android.os.Bundle;
import com.phonegap.*;
public class #{ @name } extends DroidGap
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.loadUrl(\"file:///android_asset/www/index.html\");
}
}
"
code_dir = File.join(@path, "src", @pkg.gsub('.', File::SEPARATOR))
FileUtils.mkdir_p(code_dir)
open(File.join(code_dir, "#{@name}.java"),'w') { |f| f.puts j.gsub(' ','') }
end
#
end
if ARGV.length == 5
Build.new(*ARGV).run
else
puts <<-EOF
DroidGap: PhoneGap/Android Project Generator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Creates a fresh app for hybrid mobile web hacking. Delicious robot!
Usage:
./droidgap <android_sdk_path> <name> <package_name> <www> <path>
Params:
android_sdk_path ... The path to your Android SDK install.
name ............... The name of your application.
package_name ....... The name of your package (For example: com.nitobi.demo)
www ................ The path to your www folder. (Wherein your HTML, CSS and JS app is.)
path ............... The path to generate the Android application.
EOF
end

View File

@@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=320; user-scalable=no" />

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.phonegap" android:versionName="1.1" android:versionCode="3">
package="com.phonegap" android:versionName="1.1" android:versionCode="5">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
@@ -32,12 +32,12 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".CameraPreview"
<activity android:name="com.phonegap.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="3" />
<uses-sdk android:minSdkVersion="2" />
</manifest>

View File

@@ -1,6 +0,0 @@
Note: phonegap.js goes in the assets/www directory. To get this file, please
build it from the top level by running make:
make
The file will be concatenated and minified, and will be stored in lib/android

View File

@@ -3,20 +3,12 @@ function Acceleration(x, y, z)
this.x = x;
this.y = y;
this.z = z;
this.timestamp = new Date().getTime();
this.win = null;
this.fail = null;
}
// 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;
}
var accelListeners = [];
/**
* This class provides access to device accelerometer data.
@@ -44,12 +36,34 @@ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, 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);
if(this.lastAcceleration)
successCallback(accel);
else
{
watchAcceleration(this.gotCurrentAcceleration, this.fail);
}
}
}
Accelerometer.prototype.gotAccel = function(key, x, y, z)
{
console.log('we won');
var a = new Acceleration(x,y,z);
a.x = x;
a.y = y;
a.x = z;
a.win = accelListeners[key].win;
a.fail = accelListeners[key].fail;
this.timestamp = new Date().getTime();
this.lastAcceleration = a;
accelListeners[key] = a;
if (typeof a.win == "function") {
a.win(a);
}
}
/**
* Asynchronously aquires the acceleration repeatedly at a given interval.
* @param {Function} successCallback The function to call each time the acceleration
@@ -62,12 +76,13 @@ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, error
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);
var frequency = (options != undefined)? options.frequency : 10000;
var accel = Acceleration(0,0,0);
accel.win = successCallback;
accel.fail = errorCallback;
accel.opts = options;
var key = accelListeners.push( accel ) - 1;
Accel.start(frequency, key);
}
/**
@@ -75,8 +90,11 @@ Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallb
* @param {String} watchId The ID of the watch returned from #watchAcceleration.
*/
Accelerometer.prototype.clearWatch = function(watchId) {
Accel.stop();
clearInterval(watchId);
Accel.stop(watchId);
}
Accelerometer.prototype.epicFail = function(watchId, message) {
accelWatcher[key].fail();
}
PhoneGap.addConstructor(function() {

View File

@@ -1,5 +1,5 @@
var Contact = function(){
this.name = null;
this.name = new ContactName();
this.emails = [];
this.phones = [];
}
@@ -37,7 +37,18 @@ Contacts.prototype.find = function(obj, win, fail)
{
if(obj.name != null)
{
ContactHook.search(name, "", "");
// 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;

View File

@@ -0,0 +1,33 @@
var Crypto = function()
{
}
Crypto.prototype.encrypt = function(seed, string, callback)
{
GapCrypto.encrypt(seed, string);
this.encryptWin = callback;
}
Crypto.prototype.decrypt = function(seed, string, callback)
{
GapCrypto.decrypt(seed, string);
this.decryptWin = callback;
}
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();
}
});

View File

@@ -17,7 +17,11 @@ function Device() {
this.version = window.DroidGap.getOSVersion();
this.gapVersion = window.DroidGap.getVersion();
this.platform = window.DroidGap.getPlatform();
this.name = window.DroidGap.getProductName();
this.name = window.DroidGap.getProductName();
this.line1Number = window.DroidGap.getLine1Number();
this.deviceId = window.DroidGap.getDeviceId();
this.simSerialNumber = window.DroidGap.getSimSerialNumber();
this.subscriberId = window.DroidGap.getSubscriberId();
}
} catch(e) {
this.available = false;

226
framework/assets/js/file.js Normal file
View File

@@ -0,0 +1,226 @@
PhoneGap.addConstructor(function() { if (typeof navigator.fileMgr == "undefined") navigator.fileMgr = new FileMgr();});
/**
* This class provides iPhone read and write access to the mobile device file system.
* Based loosely on http://www.w3.org/TR/2009/WD-FileAPI-20091117/#dfn-empty
*/
function FileMgr()
{
this.fileWriters = {}; // empty maps
this.fileReaders = {};
this.docsFolderPath = "../../Documents";
this.tempFolderPath = "../../tmp";
this.freeDiskSpace = -1;
this.getFileBasePaths();
}
// private, called from Native Code
FileMgr.prototype._setPaths = function(docs,temp)
{
this.docsFolderPath = docs;
this.tempFolderPath = temp;
}
// private, called from Native Code
FileMgr.prototype._setFreeDiskSpace = function(val)
{
this.freeDiskSpace = val;
}
// FileWriters add/remove
// called internally by writers
FileMgr.prototype.addFileWriter = function(filePath,fileWriter)
{
this.fileWriters[filePath] = fileWriter;
}
FileMgr.prototype.removeFileWriter = function(filePath)
{
this.fileWriters[filePath] = null;
}
// File readers add/remove
// called internally by readers
FileMgr.prototype.addFileReader = function(filePath,fileReader)
{
this.fileReaders[filePath] = fileReader;
}
FileMgr.prototype.removeFileReader = function(filePath)
{
this.fileReaders[filePath] = null;
}
/*******************************************
*
* private reader callback delegation
* called from native code
*/
FileMgr.prototype.reader_onloadstart = function(filePath,result)
{
this.fileReaders[filePath].onloadstart(result);
}
FileMgr.prototype.reader_onprogress = function(filePath,result)
{
this.fileReaders[filePath].onprogress(result);
}
FileMgr.prototype.reader_onload = function(filePath,result)
{
this.fileReaders[filePath].result = unescape(result);
this.fileReaders[filePath].onload(this.fileReaders[filePath].result);
}
FileMgr.prototype.reader_onerror = function(filePath,err)
{
this.fileReaders[filePath].result = err;
this.fileReaders[filePath].onerror(err);
}
FileMgr.prototype.reader_onloadend = function(filePath,result)
{
this.fileReaders[filePath].onloadend(result);
}
/*******************************************
*
* private writer callback delegation
* called from native code
*/
FileMgr.prototype.writer_onerror = function(filePath,err)
{
this.fileWriters[filePath].onerror(err);
}
FileMgr.prototype.writer_oncomplete = function(filePath,result)
{
this.fileWriters[filePath].oncomplete(result); // result contains bytes written
}
FileMgr.prototype.getFileBasePaths = function()
{
//PhoneGap.exec("File.getFileBasePaths");
}
FileMgr.prototype.testFileExists = function(fileName, successCallback, errorCallback)
{
var test = FileUtil.testFileExists(fileName);
test ? successCallback() : errorCallback();
}
FileMgr.prototype.testDirectoryExists = function(dirName, successCallback, errorCallback)
{
this.successCallback = successCallback;
this.errorCallback = errorCallback;
var test = FileUtil.testDirectoryExists(dirName);
test ? successCallback() : errorCallback();
}
FileMgr.prototype.createDirectory = function(dirName, successCallback, errorCallback)
{
this.successCallback = successCallback;
this.errorCallback = errorCallback;
var test = FileUtils.createDirectory(dirName);
test ? successCallback() : errorCallback();
}
FileMgr.prototype.deleteDirectory = function(dirName, successCallback, errorCallback)
{
this.successCallback = successCallback;
this.errorCallback = errorCallback;
var test = FileUtils.deleteDirectory(dirName);
test ? successCallback() : errorCallback();
}
FileMgr.prototype.deleteFile = function(fileName, successCallback, errorCallback)
{
this.successCallback = successCallback;
this.errorCallback = errorCallback;
FileUtils.deleteFile(fileName);
test ? successCallback() : errorCallback();
}
FileMgr.prototype.getFreeDiskSpace = function(successCallback, errorCallback)
{
if(this.freeDiskSpace > 0)
{
return this.freeDiskSpace;
}
else
{
this.successCallback = successCallback;
this.errorCallback = errorCallback;
this.freeDiskSpace = FileUtils.getFreeDiskSpace();
(this.freeDiskSpace > 0) ? successCallback() : errorCallback();
}
}
// File Reader
function FileReader()
{
this.fileName = "";
this.result = null;
this.onloadstart = null;
this.onprogress = null;
this.onload = null;
this.onerror = null;
this.onloadend = null;
}
FileReader.prototype.abort = function()
{
// Not Implemented
}
FileReader.prototype.readAsText = function(file)
{
if(this.fileName && this.fileName.length > 0)
{
navigator.fileMgr.removeFileReader(this.fileName,this);
}
this.fileName = file;
navigator.fileMgr.addFileReader(this.fileName,this);
return FileUtil.read(this.fileName);
}
// File Writer
function FileWriter()
{
this.fileName = "";
this.result = null;
this.readyState = 0; // EMPTY
this.result = null;
this.onerror = null;
this.oncomplete = null;
}
FileWriter.prototype.writeAsText = function(file,text,bAppend)
{
if(this.fileName && this.fileName.length > 0)
{
navigator.fileMgr.removeFileWriter(this.fileName,this);
}
this.fileName = file;
if(bAppend != true)
{
bAppend = false; // for null values
}
navigator.fileMgr.addFileWriter(file,this);
this.readyState = 0; // EMPTY
var call = FileUtil.write(file, text, bAppend);
this.result = null;
}

View File

@@ -0,0 +1,90 @@
/**
* This class provides access to device GPS data.
* @constructor
*/
function Geolocation() {
/**
* The last known GPS position.
*/
this.lastPosition = null;
this.lastError = null;
this.listeners = null;
};
var geoListeners = [];
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.lastPosition = loc;
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;
var key = geoListeners.push( {"success" : successCallback, "fail" : errorCallback }) - 1;
// TO-DO: Get the names of the method and pass them as strings to the Java.
return Geo.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);
geoListeners[key].success(loc);
}
Geolocation.prototype.fail = function(key)
{
geoListeners[key].fail();
}
Geolocation.prototype.clearWatch = function(watchId)
{
Geo.stop(watchId);
}
PhoneGap.addConstructor(function() {
// Taken from Jesse's geo fix (similar problem) in PhoneGap iPhone. Go figure, same browser!
function __proxyObj(origObj, proxyObj, funkList) {
for (var v in funkList) {
origObj[funkList[v]] = proxyObj[funkList[v]];
}
}
// In case a native geolocation object exists, proxy the native one over to a diff object so that we can overwrite the native implementation.
if (typeof navigator.geolocation != 'undefined') {
navigator._geo = new Geolocation();
__proxyObj(navigator.geolocation, navigator._geo, ["setLocation", "getCurrentPosition", "watchPosition", "clearWatch", "setError", "start", "stop", "gotCurrentPosition"]);
} else {
navigator.geolocation = new Geolocation();
}
});

View File

@@ -6,11 +6,9 @@ function NetworkStatus() {
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
@@ -23,16 +21,6 @@ function Network() {
*/
this.lastReachability = null;
};
/**
*
* @param {Function} successCallback
* @param {Function} errorCallback
* @param {Object} options (isIpAddress:boolean)
*/
Network.prototype.isReachable = function(hostName, successCallback, options) {
}
/**
* Called by the geolocation framework when the reachability status has changed.
* @param {Reachibility} reachability The current reachability status.
@@ -40,21 +28,27 @@ Network.prototype.isReachable = function(hostName, successCallback, options) {
Network.prototype.updateReachability = function(reachability) {
this.lastReachability = reachability;
};
PhoneGap.addConstructor(function() {
if (typeof navigator.network == "undefined") navigator.network = new Network();
});
/**
*
* @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 = 2;
else
status.code = 1;
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;
}
else
status.code = 0;
win(status);
}
};
PhoneGap.addConstructor(function() {
if (typeof navigator.network == "undefined") navigator.network = new Network();
});

View File

@@ -72,7 +72,7 @@ PhoneGap.addConstructor = function(func) {
e.initEvent('deviceready');
document.dispatchEvent(e);
}
}, 1);
}, 5);
})();

View File

@@ -80,10 +80,10 @@ var dbSetup = function(name, version, display_name, size)
}
PhoneGap.addConstructor(function() {
if (typeof navigator.openDatabase == "undefined")
if (typeof window.openDatabase == "undefined")
{
navigator.openDatabase = window.openDatabase = dbSetup;
window.droiddb = new DroidDB();
window.droiddb = new DroidDB();
}
});

View File

@@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="PhoneGap">
<project name="PhoneGap" default="help">
<!-- 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
It contains the path to the SDK. It should *NOT* be checked in in Version
Control Systems. -->
<property file="local.properties"/>
<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
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'.
source.dir
the name of the source directory. Default is 'src'.
out.dir
the name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should be updated
using the 'android' tool with the 'update' action.
@@ -26,47 +26,48 @@
should be checked in in Version Control Systems.
-->
<property file="build.properties"/>
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android' tool, as well
as ADT.
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"/>
<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" />
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
<pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
<pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs"/>
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.
-->
and import the build rules files.
The rules file is imported from
<SDK>/platforms/<target_platform>/templates/android_rules.xml
To customize some build steps for your project:
- copy the content of the main node <project> from android_rules.xml
- paste it in this build.xml below the <setup /> task.
- disable the import by changing the setup task below to <setup import="false" />
This will ensure that the properties are setup correctly but that your customized
build steps are used.
-->
<setup />
<!-- Grab the files, concatenate them and shove them in the
assets directory -->
<target name="move_files">
<concat destfile="assets/www/phonegap.js">
<fileset dir="../js" includes="phonegap.js.base" />
<fileset dir="../js" includes="*.js" />
<concat destfile="../example/phonegap.js">
<fileset dir="assets/js" includes="phonegap.js.base" />
<fileset dir="assets/js" includes="*.js" />
</concat>
</target>
@@ -75,9 +76,10 @@
</target>
<target name="phonegap_debug" depends="move_files, debug">
</target>
</target>
<target name="phonegap_release" depends="move_files, release">
</target>
</project>

View File

@@ -7,8 +7,8 @@
# "build.properties", and override values to adapt the script to your
# project structure.
apk-configurations=
# Project target.
target=android-5
# Indicates whether an apk should be generated for each density.
split.density=false
# Project target.
target=android-8
apk-configurations=

View File

@@ -24,7 +24,6 @@ public final class R {
}
public static final class string {
public static final int app_name=0x7f040000;
public static final int go=0x7f040002;
public static final int url=0x7f040001;
public static final int go=0x7f040001;
}
}

View File

@@ -1,10 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk-location=/home/bowserj/android-sdk-linux_x86-1.6_r1

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PhoneGap</string>
<string name="url">file:///android_asset/www/index.html</string>
<string name="go">Snap</string>
<string name="go">Snap</string>
</resources>

View File

@@ -0,0 +1,34 @@
package com.phonegap;
import java.util.HashMap;
import android.content.Context;
import android.webkit.WebView;
public class AccelBroker {
private WebView mAppView;
private Context mCtx;
private HashMap<String, AccelListener> accelListeners;
public AccelBroker(WebView view, Context ctx)
{
mCtx = ctx;
mAppView = view;
accelListeners = new HashMap<String, AccelListener>();
}
public String start(int freq, String key)
{
AccelListener listener = new AccelListener(key, freq, mCtx, mAppView);
listener.start(freq);
accelListeners.put(key, listener);
return key;
}
public void stop(String key)
{
AccelListener acc = accelListeners.get(key);
acc.stop();
}
}

View File

@@ -15,7 +15,7 @@ public class AccelListener implements SensorEventListener{
WebView mAppView;
Context mCtx;
String mKey;
Sensor mSensor;
Sensor mSensor;
int mTime = 10000;
boolean started = false;
@@ -23,10 +23,12 @@ public class AccelListener implements SensorEventListener{
private long lastUpdate = -1;
public AccelListener(Context ctx, WebView appView)
public AccelListener(String key, int freq, Context ctx, WebView appView)
{
mCtx = ctx;
mAppView = appView;
mKey = key;
mTime = freq;
sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE);
}
@@ -38,11 +40,11 @@ public class AccelListener implements SensorEventListener{
if (list.size() > 0)
{
this.mSensor = list.get(0);
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_NORMAL);
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_FASTEST);
}
else
{
// Call fail
mAppView.loadUrl("javascript:navigator.accelerometer.epicFail(" + mKey + ", 'Failed to start')");
}
}
@@ -68,8 +70,9 @@ public class AccelListener implements SensorEventListener{
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
mAppView.loadUrl("javascript:gotAccel(" + x + ", " + y + "," + z + " )");
float z = event.values[2];
//mAppView.loadUrl("javascript:gotAccel(" + x + ", " + y + "," + z + " )");
mAppView.loadUrl("javascript:navigator.accelerometer.gotAccel(" + mKey + "," + x + "," + y + "," + z + ")");
}
}

View File

@@ -0,0 +1,37 @@
package com.phonegap;
import android.webkit.WebView;
public class CryptoHandler {
WebView mView;
CryptoHandler(WebView view)
{
mView = view;
}
public void encrypt(String pass, String text)
{
try {
String encrypted = SimpleCrypto.encrypt(pass,text);
mView.loadUrl("javascript:Crypto.gotCryptedString('" + text + "')");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void decrypt(String pass, String text)
{
try {
String decrypted = SimpleCrypto.decrypt(pass,text);
mView.loadUrl("javascript:Crypto.gotPlainString('" + text + "')");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@@ -30,6 +30,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
@@ -41,6 +42,7 @@ import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.widget.LinearLayout;
import android.os.Build.*;
@@ -53,15 +55,14 @@ public class DroidGap extends Activity {
private PhoneGap gap;
private GeoBroker geo;
private AccelListener accel;
private AccelBroker accel;
private CameraLauncher launcher;
private ContactManager mContacts;
private FileUtils fs;
private NetworkManager netMan;
private CompassListener mCompass;
private Storage cupcakeStorage;
private CryptoHandler crypto;
/** Called when the activity is first created. */
@Override
@@ -87,16 +88,16 @@ public class DroidGap extends Activity {
appView.setLayoutParams(webviewParams);
WebViewReflect.checkCompatibility();
/* This changes the setWebChromeClient to log alerts to LogCat! Important for Javascript Debugging */
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ECLAIR)
if (android.os.Build.VERSION.RELEASE.startsWith("2."))
appView.setWebChromeClient(new EclairClient(this));
else
{
appView.setWebChromeClient(new GapClient(this));
cupcakeStorage = new Storage(appView);
}
appView.setWebViewClient(new GapViewClient(this));
appView.setInitialScale(100);
appView.setVerticalScrollBarEnabled(false);
@@ -104,17 +105,23 @@ public class DroidGap extends Activity {
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
Package pack = this.getClass().getPackage();
String appPackage = pack.getName();
WebViewReflect.setStorage(settings, true, "/data/data/" + appPackage + "/app_database/");
// Turn on DOM storage!
WebViewReflect.setDomStorage(settings);
// Turn off native geolocation object in browser - we use our own :)
WebViewReflect.setGeolocationEnabled(settings, false);
/* Bind the appView object to the gap class methods */
bindBrowser(appView);
if(cupcakeStorage != null)
cupcakeStorage.setStorage(appPackage);
root.addView(appView);
root.addView(appView);
setContentView(root);
}
@@ -128,12 +135,13 @@ public class DroidGap extends Activity {
{
gap = new PhoneGap(this, appView);
geo = new GeoBroker(appView, this);
accel = new AccelListener(this, appView);
accel = new AccelBroker(appView, this);
launcher = new CameraLauncher(appView, this);
mContacts = new ContactManager(this, appView);
fs = new FileUtils(appView);
netMan = new NetworkManager(this, appView);
mCompass = new CompassListener(this, appView);
mCompass = new CompassListener(this, appView);
crypto = new CryptoHandler(appView);
// This creates the new javascript interfaces for PhoneGap
appView.addJavascriptInterface(gap, "DroidGap");
@@ -144,7 +152,10 @@ public class DroidGap extends Activity {
appView.addJavascriptInterface(fs, "FileUtil");
appView.addJavascriptInterface(netMan, "NetworkManager");
appView.addJavascriptInterface(mCompass, "CompassHook");
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.DONUT)
appView.addJavascriptInterface(crypto, "GapCrypto");
if (android.os.Build.VERSION.RELEASE.startsWith("1."))
{
cupcakeStorage = new Storage(appView);
appView.addJavascriptInterface(cupcakeStorage, "droidStorage");
@@ -157,6 +168,56 @@ public class DroidGap extends Activity {
appView.loadUrl(url);
}
public class GapViewClient extends WebViewClient {
Context mCtx;
public GapViewClient(Context ctx)
{
mCtx = ctx;
}
/*
* (non-Javadoc)
* @see android.webkit.WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String)
*
* Note: Since we override it to make sure that we are using PhoneGap and not some other bullshit
* viewer that may or may not exist, we need to make sure that http:// and tel:// still work.
*
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO: See about using a switch statement
if (url.startsWith("http://"))
{
Intent browse = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browse);
return true;
}
else if(url.startsWith("tel://"))
{
Intent dial = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
startActivity(dial);
return true;
}
else if(url.startsWith("sms:"))
{
Uri smsUri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, smsUri);
intent.setType("vnd.android-dir/mms-sms");
startActivity(intent);
return true;
}
else
{
view.loadUrl(url);
return false;
}
}
}
/**
* Provides a hook for calling "alert" from javascript. Useful for
* debugging your javascript.
@@ -213,7 +274,8 @@ public class DroidGap extends Activity {
public final class EclairClient extends GapClient
{
private long MAX_QUOTA = 2000000;
private String TAG = "PhoneGapLog";
private long MAX_QUOTA = 100 * 1024 * 1024;
public EclairClient(Context ctx) {
super(ctx);
@@ -223,10 +285,13 @@ public class DroidGap extends Activity {
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
{
Log.d(TAG, "event raised onExceededDatabaseQuota estimatedSize: " + Long.toString(estimatedSize) + " currentQuota: " + Long.toString(currentQuota) + " totalUsedQuota: " + Long.toString(totalUsedQuota));
if( estimatedSize < MAX_QUOTA)
{
long newQuota = estimatedSize;
{
//increase for 1Mb
long newQuota = currentQuota + 1024*1024;
Log.d(TAG, "calling quotaUpdater.updateQuota newQuota: " + Long.toString(newQuota) );
quotaUpdater.updateQuota(newQuota);
}
else
@@ -234,8 +299,21 @@ public class DroidGap extends Activity {
// Set the quota to whatever it is and force an error
// TODO: get docs on how to handle this properly
quotaUpdater.updateQuota(currentQuota);
}
}
}
// This is a test of console.log, because we don't have this in Android 2.01
public void addMessageToConsole(String message, int lineNumber, String sourceID)
{
Log.d(TAG, sourceID + ": Line " + Integer.toString(lineNumber) + " : " + message);
}
// console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html
public void onConsoleMessage(String message, int lineNumber, String sourceID)
{
Log.d(TAG, sourceID + ": Line " + Integer.toString(lineNumber) + " : " + message);
}
}

View File

@@ -97,7 +97,7 @@ public class FileUtils {
data = "FAIL: IO ERROR";
}
mView.loadUrl("javascript:navigator.file.hasRead('" + data + "')");
//mView.loadUrl("javascript:navigator.FileReader.hasRead('" + data + "')");
return data;
}
@@ -113,9 +113,11 @@ public class FileUtils {
out.write(buff, 0, rawData.length);
out.flush();
out.close();
mView.loadUrl("javascript:navigator.file.winCallback('File written')");
//mView.loadUrl("javascript:navigator.FileReader.onsuccess('File written')");
} catch (Exception e) {
mView.loadUrl("javascript:navigator.file.failCallback('Fail')");
//mView.loadUrl("javascript:navigator.FileReader.onerror('Fail')");
// So, do we just return -1 at this point!
return -1;
}
return 0;
}

View File

@@ -21,6 +21,7 @@ public class GeoBroker {
{
mCtx = ctx;
mAppView = view;
geoListeners = new HashMap<String, GeoListener>();
}
public void getCurrentLocation()

View File

@@ -2,6 +2,7 @@ package com.phonegap;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.webkit.WebView;
public class GeoListener {
@@ -10,6 +11,7 @@ public class GeoListener {
String failCallback;
GpsListener mGps;
NetworkListener mNetwork;
LocationManager mLocMan;
Context mCtx;
private WebView mAppView;
@@ -20,8 +22,14 @@ public class GeoListener {
id = i;
interval = time;
mCtx = ctx;
mGps = new GpsListener(mCtx, interval, this);
mNetwork = new NetworkListener(mCtx, interval, this);
mGps = null;
mNetwork = null;
mLocMan = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);
if (mLocMan.getProvider(LocationManager.GPS_PROVIDER) != null)
mGps = new GpsListener(mCtx, interval, this);
if (mLocMan.getProvider(LocationManager.NETWORK_PROVIDER) != null)
mNetwork = new NetworkListener(mCtx, interval, this);
mAppView = appView;
}
@@ -39,7 +47,7 @@ public class GeoListener {
params += "," + loc.getSpeed() + "," + loc.getTime();
if(id != "global")
{
mAppView.loadUrl("javascript:navigator.geolocation.success(" + id + "," + params + ")");
mAppView.loadUrl("javascript:navigator._geo.success(" + id + "," + params + ")");
}
}
@@ -47,25 +55,31 @@ public class GeoListener {
{
// Do we need to know why? How would we handle this?
if (id != "global") {
mAppView.loadUrl("javascript:navigator.geolocation.fail(" + id + ")");
mAppView.loadUrl("javascript:navigator._geo.fail(" + id + ")");
}
else
{
mAppView.loadUrl("javascript:navigator.geolocation.fail()");
mAppView.loadUrl("javascript:navigator._geo.fail()");
}
}
// This stops the listener
void stop()
{
mGps.stop();
mNetwork.stop();
if(mGps != null)
mGps.stop();
if(mNetwork != null)
mNetwork.stop();
}
public Location getCurrentLocation() {
Location loc = mGps.getLocation();
if (loc == null)
Location loc = null;
if (mGps != null)
loc = mGps.getLocation();
if (loc == null && mNetwork != null)
loc = mNetwork.getLocation();
if(loc == null)
loc = new Location(LocationManager.NETWORK_PROVIDER);
return loc;
}
}

View File

@@ -32,8 +32,12 @@ public class NetworkManager {
public boolean isWifiActive()
{
NetworkInfo info = sockMan.getActiveNetworkInfo();
String type = info.getTypeName();
return type.equals("WIFI");
if(info != null)
{
String type = info.getTypeName();
return type.equals("WIFI");
}
return false;
}
public boolean isReachable(String uri)
@@ -50,6 +54,4 @@ public class NetworkManager {
}
return reached;
}
}

View File

@@ -1,69 +0,0 @@
package com.phonegap;
/* License (MIT)
* Copyright (c) 2008 Nitobi
* website: http://phonegap.com
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* “Software”), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import android.content.Context;
import android.hardware.SensorManager;
import android.hardware.SensorListener;
import android.webkit.WebView;
public class Orientation implements SensorListener{
private WebView mAppView;
private SensorManager sensorManager;
private Context mCtx;
Orientation(WebView kit, Context ctx) {
mAppView = kit;
mCtx = ctx;
sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE);
this.resumeAccel();
}
public void onSensorChanged(int sensor, final float[] values) {
if (sensor != SensorManager.SENSOR_ACCELEROMETER || values.length < 3)
return;
float x = values[0];
float y = values[1];
float z = values[2];
mAppView.loadUrl("javascript:gotAcceleration(" + x + ", " + y + "," + z + ")");
}
public void onAccuracyChanged(int arg0, int arg1) {
// This is a stub method.
}
public void pauseAccel()
{
sensorManager.unregisterListener(this);
}
public void resumeAccel()
{
sensorManager.registerListener(this,
SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_GAME);
}
}

View File

@@ -42,7 +42,7 @@ public class PhoneGap{
* UUID, version and availability
*/
public boolean droid = true;
public static String version = "0.8.0";
public static String version = "0.9.99999";
public static String platform = "Android";
public static String uuid;
private Context mCtx;
@@ -86,7 +86,23 @@ public class PhoneGap{
String uuid = Settings.Secure.getString(mCtx.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
return uuid;
}
public String getLine1Number(){
TelephonyManager operator = (TelephonyManager)mCtx.getSystemService(Context.TELEPHONY_SERVICE);
return operator.getLine1Number();
}
public String getDeviceId(){
TelephonyManager operator = (TelephonyManager)mCtx.getSystemService(Context.TELEPHONY_SERVICE);
return operator.getDeviceId();
}
public String getSimSerialNumber(){
TelephonyManager operator = (TelephonyManager)mCtx.getSystemService(Context.TELEPHONY_SERVICE);
return operator.getSimSerialNumber();
}
public String getSubscriberId(){
TelephonyManager operator = (TelephonyManager)mCtx.getSystemService(Context.TELEPHONY_SERVICE);
return operator.getSubscriberId();
}
public String getModel()
{

View File

@@ -0,0 +1,96 @@
/*
* Code originally found on Android Snippets
* Contributed to snippets Ferenc Hechler
* Copyright (c) 2009 Ferenc Hechler
*/
package com.phonegap;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class SimpleCrypto {
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted) throws Exception {
byte [] rawKey = getRawKey(seed.getBytes());
byte [] enc = toByte(encrypted);
byte [] result = decrypt(rawKey, enc);
return new String(result);
}
public static byte[] getRawKey(byte [] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt)
{
return toHex(txt.getBytes());
}
public static String fromHex(String hex)
{
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; ++i)
{
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
}
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
{
return "";
}
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++)
{
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "01234567890ABCDEF";
private static void appendHex(StringBuffer sb, byte b)
{
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}

View File

@@ -11,22 +11,7 @@ public class StandAlone extends DroidGap {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Load a URI from the strings.xml file */
Class<R.string> c = R.string.class;
Field f;
String uri;
int i = 0;
try {
f = c.getField("url");
i = f.getInt(f);
uri = this.getResources().getString(i);
} catch (Exception e)
{
uri = "http://www.phonegap.com";
}
super.loadUrl(uri);
super.loadUrl("file:///android_asset/www/index.html");
}
}

View File

@@ -1,5 +1,6 @@
package com.phonegap;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.*;
import android.util.Log;
@@ -12,19 +13,25 @@ public class Storage {
String path;
String txid = "";
WebView appView;
Context mCtx;
Storage(WebView view)
{
Package pack = this.getClass().getPackage();
String appPackage = pack.getName();
path = "/data/data/" + appPackage + "/databases/";
{
appView = view;
}
public void setStorage(String appPackage)
{
path = "/data/data/" + appPackage + "/databases/";
}
public void openDatabase(String db, String version, String display_name, long size)
{
path += db + ".db";
myDb = SQLiteDatabase.openOrCreateDatabase(path, null);
if (path != null)
{
path += db + ".db";
myDb = SQLiteDatabase.openOrCreateDatabase(path, null);
}
}
public void executeSql(String query, String[] params, String tx_id)

View File

@@ -9,6 +9,9 @@ import android.webkit.WebSettings;
public class WebViewReflect {
private static Method mWebSettings_setDatabaseEnabled;
private static Method mWebSettings_setDatabasePath;
private static Method mWebSettings_setDomStorageEnabled;
private static Method mWebSettings_setGeolocationEnabled;
static
{
checkCompatibility();
@@ -37,12 +40,17 @@ public class WebViewReflect {
}
}
public static void checkCompatibility() {
try {
mWebSettings_setDatabaseEnabled = WebSettings.class.getMethod(
"setDatabaseEnabled", new Class[] { boolean.class } );
mWebSettings_setDatabasePath = WebSettings.class.getMethod(
"setDatabasePath", new Class[] { String.class });
mWebSettings_setDomStorageEnabled = WebSettings.class.getMethod(
"setDomStorageEnabled", new Class[] { boolean.class });
mWebSettings_setGeolocationEnabled = WebSettings.class.getMethod(
"setGeolocationEnabled", new Class[] { boolean.class });
/* success, this is a newer device */
} catch (NoSuchMethodException nsme) {
/* failure, must be older device */
@@ -53,8 +61,49 @@ public class WebViewReflect {
if (mWebSettings_setDatabaseEnabled != null) {
/* feature is supported */
try {
mWebSettings_setDatabaseEnabled.invoke(setting, true);
mWebSettings_setDatabaseEnabled.invoke(setting, enable);
mWebSettings_setDatabasePath.invoke(setting, path);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
/* feature not supported, do something else */
}
}
public static void setGeolocationEnabled(WebSettings setting, boolean enable) {
if (mWebSettings_setGeolocationEnabled != null) {
/* feature is supported */
try {
mWebSettings_setGeolocationEnabled.invoke(setting, enable);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
/* feature not supported, do something else */
System.out.println("Native Geolocation not supported - we're ok");
}
}
public static void setDomStorage(WebSettings setting)
{
if(mWebSettings_setDomStorageEnabled != null)
{
/* feature is supported */
try {
mWebSettings_setDomStorageEnabled.invoke(setting, true);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -65,11 +114,9 @@ public class WebViewReflect {
// TODO Auto-generated catch block
e.printStackTrace();
}
//setting.setDatabaseEnabled(enable);
//setting.setDatabasePath(path);
} else {
/* feature not supported, do something else */
System.out.println("dump not supported");
}
}
}

View File

@@ -1,109 +0,0 @@
/**
* 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();
});
File.prototype.read = function(fileName, successCallback, errorCallback) {
this.failCallback = errorCallback;
this.winCallback = successCallback;
return FileUtil.read(fileName);
}
File.prototype.hasRead = function(data)
{
if(data.substr("FAIL"))
this.failCallback(data);
else
this.winCallback(data);
}
/**
* Writes a file to the mobile device.
* @param {File} file The file to write to the device.
*/
File.prototype.write = function(file, str, mode, successCallback, failCallback) {
this.winCallback = successCallback;
this.failCallback = failCallback;
var call = FileUtil.write(file, str, mode);
}
File.prototype.testFileExists = function(file, successCallback, failCallback)
{
var exists = FileUtil.testFileExists(file);
if(exists)
successCallback();
else
failCallback();
return exists;
}
File.prototype.testDirectoryExists = function(file, successCallback, failCallback)
{
var exists = FileUtil.testDirectoryExists(file);
if(exists)
successCallback();
else
failCallback();
return exists;
}
File.prototype.createDirectory = function(dir, successCallback, failCallback)
{
var good = FileUtils.createDirectory(dir);
good ? successCallback() : failCallback();
}
File.prototype.deleteDirectory = function(dir, successCallback, failCallback)
{
var good = FileUtils.deleteDirectory(dir);
good ? successCallback() : failCallback();
}
File.prototype.deleteFile = function(dir, successCallback, failCallback)
{
var good = FileUtils.deleteFile(dir);
good ? successCallback() : failCallback();
}
File.prototype.getFreeDiskSpace = function(successCallback, failCallback)
{
var diskSpace = FileUtils.getFreeDiskSpace();
if(diskSpace > 0)
successCallback();
else
failCallback();
return diskSpace;
}

View File

@@ -1,187 +0,0 @@
/**
* 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();
});
/*
* 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);
}

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="lib" path="libs/phonegap.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ponygap</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 File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.phonegap.plugins"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name">
<activity android:name="ponygap"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,17 +0,0 @@
# This file is used to override default values used by the Ant build system.
#
# This file must be checked in Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="ponygap" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains 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.dir
the name of the source directory. Default is 'src'.
out.dir
the name of the output directory. 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.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
<pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
<pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<setup />
<target name="jar" depends="compile">
<jar jarfile="phonegap_plugins.jar" basedir="bin/classes" excludes="**/R*.class" />
</target>
</project>

Binary file not shown.

View File

@@ -1,10 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/home/bowserj/android-sdk-linux_x86-1.6_r1

View File

@@ -1,13 +0,0 @@
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, ponygap"
/>
</LinearLayout>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ponygap</string>
</resources>

View File

@@ -1,34 +0,0 @@
package com.phonegap.plugins;
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.webkit.WebView;
public class TtsManager {
TextToSpeech voice;
Context mCtx;
WebView appView;
TtsManager(WebView view, Context ctx)
{
mCtx = ctx;
appView = view;
voice = new TextToSpeech(mCtx, ttsInitListener);
}
public void say(String text)
{
voice.speak(text, 1, null);
}
//I have no idea why you would use this? Do you have predefined speech?
private TextToSpeech.OnInitListener ttsInitListener = new TextToSpeech.OnInitListener() {
public void onInit(int status) {
}
};
}

View File

@@ -1,21 +0,0 @@
package com.phonegap.plugins;
import android.os.Bundle;
import com.phonegap.*;
public class ponygap extends DroidGap
{
/* Declare plugins here */
TtsManager tts;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
tts = new TtsManager(super.appView, this);
super.appView.addJavascriptInterface(tts, "ttsHook");
}
}