mirror of
https://github.com/apache/cordova-android.git
synced 2026-01-30 00:05:28 +08:00
Compare commits
83 Commits
0.9.0
...
accel_hack
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e55cef9c14 | ||
|
|
c1e628f44c | ||
|
|
cd5788c3ce | ||
|
|
5c8e029da1 | ||
|
|
a65b578449 | ||
|
|
7506548ae2 | ||
|
|
dfe0b6ff27 | ||
|
|
a179fbd095 | ||
|
|
9c1a1207bb | ||
|
|
4ff406f9df | ||
|
|
64671184a6 | ||
|
|
36e90c9e22 | ||
|
|
2f6a9e18d0 | ||
|
|
ceabaf1e37 | ||
|
|
020178e40b | ||
|
|
69e580136a | ||
|
|
72fd058b9e | ||
|
|
827c0ec81f | ||
|
|
887ab4a28b | ||
|
|
655c6ac130 | ||
|
|
87dd64d36c | ||
|
|
24d5948d0d | ||
|
|
f53b4ec109 | ||
|
|
915bf19378 | ||
|
|
a4cc222a43 | ||
|
|
fade602c0b | ||
|
|
f32bb7057e | ||
|
|
57a41b7b2f | ||
|
|
db03ff397f | ||
|
|
52a49aaaea | ||
|
|
941d6805ec | ||
|
|
bdf01735cd | ||
|
|
c750109bd7 | ||
|
|
6b269b85d2 | ||
|
|
1d4a67cdad | ||
|
|
64574be133 | ||
|
|
be5c31ee1c | ||
|
|
c3c5d522a3 | ||
|
|
f93c2badcc | ||
|
|
9c0259c2c1 | ||
|
|
2fa78679cb | ||
|
|
cb90852dfc | ||
|
|
c4ac7e5383 | ||
|
|
693cb4695f | ||
|
|
73b18de56f | ||
|
|
fcce200701 | ||
|
|
de8dc4af2a | ||
|
|
466c7ccaff | ||
|
|
fa2776d3d7 | ||
|
|
17d4d521e7 | ||
|
|
c8bfbab522 | ||
|
|
32e8ecc772 | ||
|
|
02c750134c | ||
|
|
b0054aa1b4 | ||
|
|
594e77690c | ||
|
|
37c3c2528d | ||
|
|
10d455d560 | ||
|
|
7820451108 | ||
|
|
3d91a98b3a | ||
|
|
c638fbfa69 | ||
|
|
17528c15bb | ||
|
|
f491a69769 | ||
|
|
bf01ba0aea | ||
|
|
76a8203176 | ||
|
|
5255f63237 | ||
|
|
0c585b7416 | ||
|
|
edd0a2caf6 | ||
|
|
91c4174f19 | ||
|
|
3862632af1 | ||
|
|
1f9571a3da | ||
|
|
c023c3d8cc | ||
|
|
4c0da8e241 | ||
|
|
e01dfec400 | ||
|
|
cf70f7d4a7 | ||
|
|
4934877515 | ||
|
|
c3cd44c04c | ||
|
|
bb7b973bf0 | ||
|
|
816341030f | ||
|
|
923c29aa2b | ||
|
|
e3dc010b97 | ||
|
|
fc6f2f5d39 | ||
|
|
4144587640 | ||
|
|
d81f53465f |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -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
21
LICENSE
Normal 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.
|
||||
61
README.md
61
README.md
@@ -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
147
assets/www/index.html
Normal 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"> </span></h4>
|
||||
<h4>Version: <span id="version"> </span></h4>
|
||||
<h4>UUID: <span id="uuid"> </span></h4>
|
||||
</div>
|
||||
<dl id="accel-data">
|
||||
<dt>X:</dt><dd id="x"> </dd>
|
||||
<dt>Y:</dt><dd id="y"> </dd>
|
||||
<dt>Z:</dt><dd id="z"> </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>
|
||||
80
build.rb
80
build.rb
@@ -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
179
droidgap
Executable 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
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
@@ -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;
|
||||
33
framework/assets/js/crypto.js
Normal file
33
framework/assets/js/crypto.js
Normal 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();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
226
framework/assets/js/file.js
Normal 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;
|
||||
}
|
||||
90
framework/assets/js/geolocation.js
Normal file
90
framework/assets/js/geolocation.js
Normal 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();
|
||||
}
|
||||
});
|
||||
@@ -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();
|
||||
});
|
||||
@@ -72,7 +72,7 @@ PhoneGap.addConstructor = function(func) {
|
||||
e.initEvent('deviceready');
|
||||
document.dispatchEvent(e);
|
||||
}
|
||||
}, 1);
|
||||
}, 5);
|
||||
})();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
34
framework/src/com/phonegap/AccelBroker.java
Normal file
34
framework/src/com/phonegap/AccelBroker.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
framework/src/com/phonegap/CryptoHandler.java
Normal file
37
framework/src/com/phonegap/CryptoHandler.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ public class GeoBroker {
|
||||
{
|
||||
mCtx = ctx;
|
||||
mAppView = view;
|
||||
geoListeners = new HashMap<String, GeoListener>();
|
||||
}
|
||||
|
||||
public void getCurrentLocation()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
96
framework/src/com/phonegap/SimpleCrypto.java
Normal file
96
framework/src/com/phonegap/SimpleCrypto.java
Normal 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));
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
109
js/file.js
109
js/file.js
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">ponygap</string>
|
||||
</resources>
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user