Merge branch 'master' of git://github.com/filmaj/phonegap-android

This commit is contained in:
Brian LeRoux 2010-02-14 23:41:20 -08:00
commit f491a69769
7 changed files with 133 additions and 119 deletions

View File

@ -1,11 +1,14 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'fileutils'
# ./droidgap /Users/brianleroux/Code/android-sdk-mac MyApp com.westcoastlogic example /Users/brianleroux/Desktop/MyApp # ./droidgap /Users/brianleroux/Code/android-sdk-mac MyApp com.westcoastlogic example /Users/brianleroux/Desktop/MyApp
class Build class Build
attr_reader :android_sdk_path, :name, :pkg, :www, :path attr_reader :android_sdk_path, :name, :pkg, :www, :path, :dir
def initialize(*a) def initialize(*a)
@android_sdk_path, @name, @pkg, @www, @path = a @android_sdk_path, @name, @pkg, @www, @path = a
@s = File::SEPARATOR
@dir = Dir.pwd + @s
end end
# runs the build script # runs the build script
@ -16,62 +19,83 @@ class Build
copy_libs copy_libs
add_name_to_strings add_name_to_strings
write_java write_java
puts "Complete!"
end end
# removes local.properties and recreates based on android_sdk_path # removes local.properties and recreates based on android_sdk_path
# then generates framework/phonegap.jar # then generates framework/phonegap.jar
def build_jar def build_jar
`rm framework/local.properties` if File.exists? 'framework/local.properties' puts "Building the JAR..."
`rm framework/phonegap.jar` if File.exists? 'framework/phonegap.jar' FileUtils.rm "#{ @dir }framework#{@s}local.properties" if File.exists? "#{ @dir }framework#{@s}local.properties"
`rm framework/phonegap.js` if File.exists? 'framework/phonegap.js' FileUtils.rm "#{ @dir }framework#{@s}phonegap.js" if File.exists? "#{ @dir }framework#{@s}phonegap.js"
`ECHO 'sdk-location=#{ @android_sdk_path }' > framework/local.properties` FileUtils.rm "#{ @dir }framework#{@s}phonegap.jar" if File.exists? "#{ @dir }framework#{@s}phonegap.jar"
`cd framework; ant jar` open("#{ @dir }framework#{@s}local.properties", 'w') do |f|
f.puts "sdk.dir=#{ @android_sdk_path }"
end
Dir.chdir(@dir + "framework")
`ant jar`
Dir.chdir(@dir)
end end
# runs android create project # runs android create project
# TODO need to allow more flexible SDK targetting # TODO need to allow more flexible SDK targetting
# TODO validate Android SDK # TODO validate Android SDK
def create_android def create_android
puts "Creating Android project..."
`android create project -t 5 -k #{ @pkg } -a #{ @name } -n #{ @name } -p #{ @path }` `android create project -t 5 -k #{ @pkg } -a #{ @name } -n #{ @name } -p #{ @path }`
FileUtils.mkdir_p "#{ @path }#{@s}assets#{@s}www"
FileUtils.cp_r "#{ @www }#{ @s }.", "#{ @path }#{ @s }assets#{ @s }www#{ @s }"
end end
# creates an AndroidManifest.xml for the project # creates an AndroidManifest.xml for the project
def generate_manifest def generate_manifest
puts "Generating manifest..."
manifest = "" manifest = ""
open('framework/AndroidManifest.xml', 'r') do |old| open(@dir + 'framework/AndroidManifest.xml', 'r') do |old|
manifest = old.read manifest = old.read
manifest.gsub! 'android:versionCode="5"', 'android:versionCode="1"' manifest.gsub! 'android:versionCode="5"', 'android:versionCode="1"'
manifest.gsub! 'package="com.phonegap"', "package=\"#{ @pkg }\"" manifest.gsub! 'package="com.phonegap"', "package=\"#{ @pkg }\""
manifest.gsub! 'android:name=".StandAlone"', "android:name=\".#{ @name }\"" manifest.gsub! 'android:name=".StandAlone"', "android:name=\".#{ @name }\""
manifest.gsub! 'android:minSdkVersion="5"', 'android:minSdkVersion="3"' manifest.gsub! 'android:minSdkVersion="5"', 'android:minSdkVersion="3"'
end end
open("#{ @path }/AndroidManifest.xml", 'w') { |x| x.puts manifest } open("#{ @path }#{@s}AndroidManifest.xml", 'w') { |x| x.puts manifest }
end end
# copies stuff from framework into the project # copies stuff from framework into the project
# TODO need to allow for www import inc icon # TODO need to allow for www import inc icon
def copy_libs def copy_libs
`mkdir -p #{ @path }/assets/wwww` puts "Copying over libraries and assets and creating phonegap.js..."
`cp framework/phonegap.jar #{ @path }/libs` FileUtils.cp "#{ @dir }framework#{@s}phonegap.jar", "#{ @path }#{@s}libs"
`cp framework/res/values/strings.xml #{ @path }/res/values/strings.xml` FileUtils.cp "#{ @dir }framework#{@s}res#{@s}values#{@s}strings.xml", "#{ @path }#{@s}res#{@s}values#{@s}strings.xml"
`cp framework/res/layout/main.xml #{ @path }/res/layout/main.xml` FileUtils.cp "#{ @dir }framework#{@s}res#{@s}layout#{@s}main.xml", "#{ @path }#{@s}res#{@s}layout#{@s}main.xml"
`cp framework/res/layout/preview.xml #{ @path }/res/layout/preview.xml` FileUtils.cp "#{ @dir }framework#{@s}res#{@s}layout#{@s}preview.xml", "#{ @path }#{@s}res#{@s}layout#{@s}preview.xml"
%w(drawable-hdpi drawable-ldpi drawable-mdpi).each do |e| %w(drawable-hdpi drawable-ldpi drawable-mdpi).each do |e|
`cp framework/res/drawable/icon.png #{ @path }/res/#{ e }/icon.png` FileUtils.cp "#{ @dir }framework#{@s}res#{@s}drawable#{@s}icon.png", "#{ @path }#{@s}res#{@s}#{ e }#{@s}icon.png"
end end
`cp -R example #{ @path }/assets` # concat JS and put into www folder.
`mv #{ @path }/assets/example #{ @path }/assets/www` Dir.chdir("#{ @dir }framework#{ @s }assets#{ @s }js")
basedir = "."
js = Dir.new(basedir).entries
phonegapjs = IO.read('phonegap.js.base');
js.each do |script|
next if script[0].chr == "." or script == "phonegap.js.base"
phonegapjs += IO.read(script)
phonegapjs += "\n\n"
end
Dir.chdir("#{ @dir}")
File.open("#{ @path }#{ @s }assets#{ @s }www#{ @s }phonegap.js", 'w') {|f| f.write(phonegapjs) }
end end
# puts app name in strings # puts app name in strings
def add_name_to_strings def add_name_to_strings
puts "Adding some application name to strings.xml..."
x = "<?xml version=\"1.0\" encoding=\"utf-8\"?> x = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<resources> <resources>
<string name=\"app_name\">#{ @name }</string> <string name=\"app_name\">#{ @name }</string>
<string name=\"go\">Snap</string> <string name=\"go\">Snap</string>
</resources> </resources>
" "
open("#{ @path }/res/values/strings.xml", 'w') do |f| open("#{ @path }#{@s}res#{@s}values#{@s}strings.xml", 'w') do |f|
f.puts x.gsub(' ','') f.puts x.gsub(' ','')
end end
end end
@ -79,6 +103,7 @@ class Build
# this is so fucking unholy yet oddly beautiful # this is so fucking unholy yet oddly beautiful
# not sure if I should thank Ruby or apologize for this abusive use of string interpolation # not sure if I should thank Ruby or apologize for this abusive use of string interpolation
def write_java def write_java
puts "Writing application Java code..."
j = " j = "
package #{ @pkg }; package #{ @pkg };
@ -96,7 +121,7 @@ class Build
} }
} }
" "
dir = "#{ @path }/src/#{ @pkg.gsub '.', '/' }"; dir = "#{ @path }#{@s}src#{@s}#{ @pkg.gsub '.', '/' }";
cls = "#{ @name }.java" cls = "#{ @name }.java"
pth = File.join(dir,cls) pth = File.join(dir,cls)
open(pth,'w') { |f| f.puts j.gsub(' ','') } open(pth,'w') { |f| f.puts j.gsub(' ','') }

View File

@ -3,10 +3,11 @@ function Acceleration(x, y, z)
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.timestamp = new Date().getTime();
} }
// Need to define these for android // Need to define these for android
_accel = {} _accel = {};
_accel.x = 0; _accel.x = 0;
_accel.y = 0; _accel.y = 0;
_accel.z = 0; _accel.z = 0;

View File

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

View File

@ -14,46 +14,12 @@ function Geolocation() {
}; };
}; };
/** Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options)
* Asynchronously aquires the current position. {
* @param {Function} successCallback The function to call when the position var position = Geo.getCurrentLocation();
* data is available this.global_success = successCallback;
* @param {Function} errorCallback The function to call when there is an error this.fail = errorCallback;
* 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. * Asynchronously aquires the position repeatedly at a given interval.
@ -112,23 +78,6 @@ Geolocation.prototype.setError = function(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 // Run the global callback
Geolocation.prototype.gotCurrentPosition = function(lat, lng, alt, altacc, head, vel, stamp) Geolocation.prototype.gotCurrentPosition = function(lat, lng, alt, altacc, head, vel, stamp)
{ {
@ -140,6 +89,7 @@ Geolocation.prototype.gotCurrentPosition = function(lat, lng, alt, altacc, head,
{ {
coords = new Coordinates(lat, lng, alt, altacc, head, vel); coords = new Coordinates(lat, lng, alt, altacc, head, vel);
loc = new Position(coords, stamp); loc = new Position(coords, stamp);
this.lastPosition = loc;
this.global_success(loc); this.global_success(loc);
} }
} }
@ -185,3 +135,16 @@ Geolocation.prototype.clearWatch = function(watchId)
{ {
Geo.stop(watchId); Geo.stop(watchId);
} }
// 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]];
}
}
PhoneGap.addConstructor(function() {
navigator._geo = new Geolocation();
__proxyObj(navigator.geolocation, navigator._geo,
["setLocation", "getCurrentPosition", "watchPosition",
"clearWatch", "setError", "start", "stop", "gotCurrentPosition"]
);
});

View File

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

View File

@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?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. <!-- 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. --> Control Systems. -->
<property file="local.properties"/> <property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched <!-- 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 by the 'android' tool. This is the place to change some of the default property values
used by the Ant rules. used by the Ant rules.
Here are some properties you may want to change/update: 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 the name of your application package as defined in the manifest. Used by the
'uninstall' rule. 'uninstall' rule.
source-folder source.dir
the name of the source folder. Default is 'src'. the name of the source directory. Default is 'src'.
out-folder out.dir
the name of the output folder. Default is 'bin'. the name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should be updated Properties related to the SDK location or the project target should be updated
using the 'android' tool with the 'update' action. using the 'android' tool with the 'update' action.
@ -26,43 +26,44 @@
should be checked in in Version Control Systems. 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 <!-- 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 This file is an integral part of the build system for your application and
should be checked in in Version Control Systems. --> 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. <!-- Custom Android task to deal with the project target, and import the proper rules.
This requires ant 1.6.0 or above. --> This requires ant 1.6.0 or above. -->
<path id="android.antlibs"> <path id="android.antlibs">
<pathelement path="${sdk-location}/tools/lib/anttasks.jar" /> <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk-location}/tools/lib/sdklib.jar" /> <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk-location}/tools/lib/androidprefs.jar" /> <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
<pathelement path="${sdk-location}/tools/lib/apkbuilder.jar" /> <pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
<pathelement path="${sdk-location}/tools/lib/jarutils.jar" /> <pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
</path> </path>
<taskdef name="setup" <taskdef name="setup"
classname="com.android.ant.SetupTask" 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, <!-- Execute the Android Setup task that will setup some properties specific to the target,
and import the rules files. and import the build rules files.
To customize the rules, copy/paste them below the task, and disable import by setting
the import attribute to false: The rules file is imported from
<setup import="false" /> <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 This will ensure that the properties are setup correctly but that your customized
targets are used. build steps are used.
--> -->
<setup /> <setup />
<!-- Grab the files, concatenate them and shove them in the
assets directory -->
<target name="move_files"> <target name="move_files">
<concat destfile="../example/phonegap.js"> <concat destfile="../example/phonegap.js">
<fileset dir="assets/js" includes="phonegap.js.base" /> <fileset dir="assets/js" includes="phonegap.js.base" />
@ -80,4 +81,5 @@
<target name="phonegap_release" depends="move_files, release"> <target name="phonegap_release" depends="move_files, release">
</target> </target>
</project> </project>

View File

@ -2,6 +2,7 @@ package com.phonegap;
import android.content.Context; import android.content.Context;
import android.location.Location; import android.location.Location;
import android.location.LocationManager;
import android.webkit.WebView; import android.webkit.WebView;
public class GeoListener { public class GeoListener {
@ -10,6 +11,7 @@ public class GeoListener {
String failCallback; String failCallback;
GpsListener mGps; GpsListener mGps;
NetworkListener mNetwork; NetworkListener mNetwork;
LocationManager mLocMan;
Context mCtx; Context mCtx;
private WebView mAppView; private WebView mAppView;
@ -20,7 +22,13 @@ public class GeoListener {
id = i; id = i;
interval = time; interval = time;
mCtx = ctx; mCtx = ctx;
mGps = null;
mNetwork = null;
mLocMan = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);
if (mLocMan.getProvider(LocationManager.GPS_PROVIDER) != null)
mGps = new GpsListener(mCtx, interval, this); mGps = new GpsListener(mCtx, interval, this);
if (mLocMan.getProvider(LocationManager.NETWORK_PROVIDER) != null)
mNetwork = new NetworkListener(mCtx, interval, this); mNetwork = new NetworkListener(mCtx, interval, this);
mAppView = appView; mAppView = appView;
} }
@ -63,9 +71,13 @@ public class GeoListener {
} }
public Location getCurrentLocation() { public Location getCurrentLocation() {
Location loc = mGps.getLocation(); Location loc = null;
if (loc == null) if (mGps != null)
loc = mGps.getLocation();
if (loc == null && mNetwork != null)
loc = mNetwork.getLocation(); loc = mNetwork.getLocation();
else
loc = new Location(LocationManager.NETWORK_PROVIDER);
return loc; return loc;
} }
} }