Compare commits

..

47 Commits

Author SHA1 Message Date
macdonst
393bd5a1f5 Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-07-11 17:28:56 -04:00
macdonst
1de036a744 Setting version as 1.0.0rc1 2011-07-12 05:25:53 +08:00
macdonst
a235513991 Setting version as 1.0.0rc1 2011-07-11 17:24:33 -04:00
macdonst
22a9cabeb9 Updating Contacts for June 16th W3C Spec 2011-07-11 23:18:24 +08:00
Bryce Curtis
5de4ae7554 Remove dependency on notification.activityStart/Stop so they can be deprecated to an optional plugin. Also remove hideLoadingDialogOnPage option, since it no longer is relevant. 2011-07-08 23:07:22 -05:00
Bryce Curtis
f19d8f9bba Change to PhoneGap naming convention affects droidgap creation & update. Also, create script uses phonegap-x.js, not phonegap-x.min.js. 2011-07-08 16:27:57 -05:00
macdonst
d4ccc702b2 Merge pull request #145 from macdonst/fixJar
Update .gitignore and .jar file name
2011-07-08 13:44:45 -07:00
macdonst
a0c748620a Update .gitignore and .jar file name 2011-07-08 16:40:55 -04:00
macdonst
b85a769372 Merge pull request #144 from macdonst/is129
Fix for #129: PhoneGap JS Naming Convention
2011-07-08 12:03:26 -07:00
macdonst
dd52081deb Fix for #129: PhoneGap JS Naming Convention 2011-07-08 14:35:31 -04:00
macdonst
ebd92a4b12 Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-07-07 16:49:22 -04:00
Bryce Curtis
0a7a77e77b Accept IPlugin for result callback when starting activities for result. 2011-07-07 14:11:03 -05:00
Bryce Curtis
9d1e73656f Merge pull request #138 from davejohnson/iplugin-fix
Update PluginManager to accept plugins implementing IPlugin too
2011-07-07 12:00:36 -07:00
macdonst
6e62a76564 Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-07-07 13:08:25 -04:00
macdonst
3895570edd Fixed Issue 140: Contact.displayName is not being set correctly 2011-07-08 01:06:27 +08:00
Fil Maj
28b01fe494 Fix for #120: zooming in on input elements when filling out forms. Note, you also have to set initial-scale and maximum-scale properties in your meta name=viewport tag. 2011-07-07 09:19:39 -07:00
macdonst
709eacd9dc Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-07-07 11:49:24 -04:00
Dave Johnson
090890b22a Update PluginManager to accept plugins that implement IPlugin rather than extend Plugin 2011-07-07 00:12:44 -07:00
Bryce Curtis
ce9d577415 Remove unused code and variable. 2011-07-06 13:56:49 -05:00
Bryce Curtis
cfc9631873 Copy plugins.xml when creating a new project. 2011-07-06 13:36:29 -05:00
Bryce Curtis
3bf48f82af Merge pull request #136 from brycecurtis/plugins
Loading plugins from res/xml/plugins.xml
2011-07-06 11:12:20 -07:00
Dave Johnson
f9bcf71a7a Merge pull request #134 from davejohnson/plugin-refactor
Plugin refactor
2011-07-06 11:10:00 -07:00
Bryce Curtis
9d5aa9406c Loading plugins from res/xml/plugins.xml 2011-07-05 23:21:32 -05:00
Dave Johnson
0b1e760fc1 Add better support for Activity result callbacks from plugins. Add some sugar for calling success / error callbacks from plugins 2011-07-05 14:13:55 -07:00
Dave Johnson
941b64f6a2 Merge branch 'master' of github.com:phonegap/phonegap-android 2011-06-30 13:43:06 -07:00
macdonst
7cc1cc4a3f Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-30 15:43:50 -04:00
Bryce Curtis
c98b758e94 Update version to 0.9.6.1 2011-06-30 13:15:30 -05:00
macdonst
102d37d48a Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-30 11:58:12 -04:00
Bryce Curtis
4b647fc58d Merge pull request #128 from brycecurtis/pages
Update version number and fix issues with prompt().
2011-06-30 08:56:53 -07:00
Bryce Curtis
b7156c6803 Bump up version to 0.9.6 for example. 2011-06-30 10:53:23 -05:00
Bryce Curtis
b8cc36e805 Don't clear activity stack by default. 2011-06-30 10:42:27 -05:00
Bryce Curtis
76b2df208e Add comment 2011-06-29 18:28:29 -05:00
Bryce Curtis
9643314553 Add more control over how url is loaded. 2011-06-29 18:25:49 -05:00
Bryce Curtis
1e3422ae70 Load new urls in new DroidGap activity - not same webview as initial url. 2011-06-29 18:23:20 -05:00
Bryce Curtis
fc1bea4947 Update version to 0.9.6. 2011-06-29 16:43:52 -05:00
macdonst
afb48e52b6 Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-29 09:55:31 -04:00
Fil Maj
b5dc62d9ef fix to build script: gotta strip out new lines from read in version string 2011-06-28 15:20:13 -07:00
macdonst
2a786044de Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-28 14:26:50 -04:00
macdonst
5c8913351c Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-27 12:34:33 -04:00
macdonst
226e4dddcd Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-24 16:43:31 -04:00
macdonst
66dbd9ef8b Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-24 10:56:05 -04:00
macdonst
1a9471a2e0 Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-22 14:48:49 -04:00
macdonst
5e733ede9f Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-16 09:57:02 -04:00
macdonst
e5fb0c0e71 Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-14 09:59:19 -04:00
macdonst
b46cbfd673 Merge branch 'master' of git://github.com/phonegap/phonegap-android 2011-06-08 15:17:36 -04:00
macdonst
fbb6b22de6 Updating Network Connection API to match spec released on June 7th 2011-06-08 15:03:03 -04:00
Dave Johnson
8f7a5decb6 Add DS_Store to gitignore 2011-05-25 17:28:24 -07:00
22 changed files with 769 additions and 375 deletions

5
.gitignore vendored
View File

@@ -1,8 +1,11 @@
.DS_Store
default.properties
gen
assets/www/phonegap.js
local.properties
framework/phonegap.jar
framework/phonegap-*.jar
framework/bin
framework/assets/www/.DS_Store
.DS_Store
framework/assets/www/phonegap-*.js
.DS_Store

View File

@@ -1 +1 @@
0.9.6
1.0.0rc1

View File

@@ -5,8 +5,8 @@
<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.0.9.5.min.js"></script>
<script type="text/javascript" charset="utf-8" src="main.js"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.0.0rc1.min.js"></script>
<script type="text/javascript" charset="utf-8" src="main.js"></script>
</head>
<body onload="init();" id="stage" class="theme">
@@ -31,8 +31,8 @@
<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>
<a href="#" class="btn large" onclick="check_network();">Check Network</a>
<div id="viewport" class="viewport" style="display: none;">
<div id="viewport" class="viewport" style="display: none;">
<img style="width:60px;height:60px" id="test_img" src="" />
</div>
</div>
</body>
</html>

View File

@@ -30,15 +30,18 @@
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:debuggable="true">
<activity android:name=".StandAlone"
<activity android:name=".StandAlone" android:windowSoftInputMode="adjustPan"
android:label="@string/app_name" android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.phonegap.DroidGap" android:label="@string/app_name">
<intent-filter>
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="2" />
<uses-sdk android:minSdkVersion="2" />
</manifest>

View File

@@ -21,17 +21,14 @@ PhoneGap.addResource("contact");
* @param {Array.<ContactAddress>} addresses array of addresses
* @param {Array.<ContactField>} ims instant messaging user ids
* @param {Array.<ContactOrganization>} organizations
* @param {DOMString} revision date contact was last updated
* @param {DOMString} birthday contact's birthday
* @param {DOMString} gender contact's gender
* @param {DOMString} note user notes about contact
* @param {Array.<ContactField>} photos
* @param {Array.<ContactField>} categories
* @param {Array.<ContactField>} urls contact's web sites
* @param {DOMString} timezone the contacts time zone
*/
var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
ims, organizations, revision, birthday, gender, note, photos, categories, urls, timezone) {
ims, organizations, birthday, note, photos, categories, urls) {
this.id = id || null;
this.rawId = null;
this.displayName = displayName || null;
@@ -42,14 +39,11 @@ var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, a
this.addresses = addresses || null; // ContactAddress[]
this.ims = ims || null; // ContactField[]
this.organizations = organizations || null; // ContactOrganization[]
this.revision = revision || null;
this.birthday = birthday || null;
this.gender = gender || null;
this.note = note || null;
this.photos = photos || null; // ContactField[]
this.categories = categories || null; // ContactField[]
this.urls = urls || null; // ContactField[]
this.timezone = timezone || null;
};
/**
@@ -66,11 +60,10 @@ var ContactError = function() {
*/
ContactError.UNKNOWN_ERROR = 0;
ContactError.INVALID_ARGUMENT_ERROR = 1;
ContactError.NOT_FOUND_ERROR = 2;
ContactError.TIMEOUT_ERROR = 3;
ContactError.PENDING_OPERATION_ERROR = 4;
ContactError.IO_ERROR = 5;
ContactError.NOT_SUPPORTED_ERROR = 6;
ContactError.TIMEOUT_ERROR = 2;
ContactError.PENDING_OPERATION_ERROR = 3;
ContactError.IO_ERROR = 4;
ContactError.NOT_SUPPORTED_ERROR = 5;
ContactError.PERMISSION_DENIED_ERROR = 20;
/**
@@ -81,7 +74,7 @@ ContactError.PERMISSION_DENIED_ERROR = 20;
Contact.prototype.remove = function(successCB, errorCB) {
if (this.id === null) {
var errorObj = new ContactError();
errorObj.code = ContactError.NOT_FOUND_ERROR;
errorObj.code = ContactError.UNKNOWN_ERROR;
errorCB(errorObj);
}
else {
@@ -197,8 +190,10 @@ var ContactField = function(type, value, pref) {
* @param postalCode
* @param country
*/
var ContactAddress = function(formatted, streetAddress, locality, region, postalCode, country) {
var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
this.id = null;
this.pref = pref || null;
this.type = type || null;
this.formatted = formatted || null;
this.streetAddress = streetAddress || null;
this.locality = locality || null;
@@ -219,8 +214,10 @@ var ContactAddress = function(formatted, streetAddress, locality, region, postal
* @param location
* @param desc
*/
var ContactOrganization = function(name, dept, title) {
var ContactOrganization = function(pref, type, name, dept, title) {
this.id = null;
this.pref = pref || null;
this.type = type || null;
this.name = name || null;
this.department = dept || null;
this.title = title || null;
@@ -243,7 +240,16 @@ var Contacts = function() {
* @return array of Contacts matching search criteria
*/
Contacts.prototype.find = function(fields, successCB, errorCB, options) {
PhoneGap.exec(successCB, errorCB, "Contacts", "search", [fields, options]);
if (successCB === null) {
throw new TypeError("You must specify a success callback for the find command.");
}
if (fields === null || fields === "undefined" || fields.length === "undefined" || fields.length <= 0) {
if (typeof errorCB === "function") {
errorCB({"code": ContactError.INVALID_ARGUMENT_ERROR});
}
} else {
PhoneGap.exec(successCB, errorCB, "Contacts", "search", [fields, options]);
}
};
/**
@@ -267,7 +273,7 @@ Contacts.prototype.create = function(properties) {
/**
* This function returns and array of contacts. It is required as we need to convert raw
* JSON objects into concrete Contact objects. Currently this method is called after
* navigator.service.contacts.find but before the find methods success call back.
* navigator.contacts.find but before the find methods success call back.
*
* @param jsonArray an array of JSON Objects that need to be converted to Contact objects.
* @returns an array of Contact objects
@@ -276,7 +282,7 @@ Contacts.prototype.cast = function(pluginResult) {
var contacts = [];
var i;
for (i=0; i<pluginResult.message.length; i++) {
contacts.push(navigator.service.contacts.create(pluginResult.message[i]));
contacts.push(navigator.contacts.create(pluginResult.message[i]));
}
pluginResult.message = contacts;
return pluginResult;
@@ -287,23 +293,18 @@ Contacts.prototype.cast = function(pluginResult) {
* @constructor
* @param filter used to match contacts against
* @param multiple boolean used to determine if more than one contact should be returned
* @param updatedSince return only contact records that have been updated on or after the given time
*/
var ContactFindOptions = function(filter, multiple, updatedSince) {
var ContactFindOptions = function(filter, multiple) {
this.filter = filter || '';
this.multiple = multiple || true;
this.updatedSince = updatedSince || '';
this.multiple = multiple || false;
};
/**
* Add the contact interface into the browser.
*/
PhoneGap.addConstructor(function() {
if(typeof navigator.service === "undefined") {
navigator.service = {};
}
if(typeof navigator.service.contacts === "undefined") {
navigator.service.contacts = new Contacts();
if(typeof navigator.contacts === "undefined") {
navigator.contacts = new Contacts();
}
});
}

View File

@@ -365,10 +365,6 @@ PhoneGap.Channel.join(function() {
// Fire onDeviceReady event once all constructors have run and PhoneGap info has been
// received from native side, and any user defined initialization channels.
PhoneGap.Channel.join(function() {
// Turn off app loading dialog
navigator.notification.activityStop();
PhoneGap.onDeviceReady.fire();
// Fire the onresume event, since first one happens before JavaScript is loaded

View File

@@ -1,7 +1,7 @@
<html>
<head>
<title></title>
<script src="phonegap.0.9.5.min.js"></script>
<script src="phonegap-1.0.0rc1.min.js"></script>
</head>
<body>

View File

@@ -40,6 +40,9 @@
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" />
<!-- We need to setup the double quote. -->
<property name="dblQuote">"</property>
<!-- Custom Android task to deal with the project target, and import the proper rules.
This requires ant 1.6.0 or above. -->
@@ -71,54 +74,54 @@
-->
<setup />
<target name="check-javascript" depends="build-javascript">
<delete dir="assets/lib"/>
<mkdir dir="assets/lib"/>
<echo file="assets/lib/lint.js">var alert=function(){},device={},Element={},debug={};</echo>
<concat destfile="assets/lib/phonegap-lint.js" append="true">
<fileset dir="assets/lib">
<include name="lint.js" />
</fileset>
<fileset dir="assets/www">
<include name="phonegap.${version}.js" />
</fileset>
</concat>
<target name="check-javascript" depends="build-javascript">
<delete dir="assets/lib"/>
<mkdir dir="assets/lib"/>
<echo file="assets/lib/lint.js">var alert=function(){},device={},Element={},debug={};</echo>
<concat destfile="assets/lib/phonegap-lint.js" append="true">
<fileset dir="assets/lib">
<include name="lint.js" />
</fileset>
<fileset dir="assets/www">
<include name="phonegap-${version}.js" />
</fileset>
</concat>
<exec executable="cmd" os="Windows 7">
<arg value="/c"/>
<arg value="java"/>
<arg value="-cp"/>
<arg value="${basedir}/util/js.jar"/>
<arg value="org.mozilla.javascript.tools.shell.Main"/>
<arg value="${basedir}/util/jslint.js"/>
<arg value="${basedir}/js/lib/phonegap-lint.js"/>
</exec>
<exec executable="java" os="Mac OS X">
<arg value="-cp"/>
<arg value="../util/js.jar"/>
<arg value="org.mozilla.javascript.tools.shell.Main"/>
<arg value="../util/jslint.js"/>
<arg value="assets/lib/phonegap-lint.js"/>
</exec>
</target>
<exec executable="cmd" os="Windows 7">
<arg value="/c"/>
<arg value="java"/>
<arg value="-cp"/>
<arg value="${basedir}/util/js.jar"/>
<arg value="org.mozilla.javascript.tools.shell.Main"/>
<arg value="${basedir}/util/jslint.js"/>
<arg value="${basedir}/js/lib/phonegap-lint.js"/>
</exec>
<exec executable="java" os="Mac OS X">
<arg value="-cp"/>
<arg value="../util/js.jar"/>
<arg value="org.mozilla.javascript.tools.shell.Main"/>
<arg value="../util/jslint.js"/>
<arg value="assets/lib/phonegap-lint.js"/>
</exec>
</target>
<!-- Combine JavaScript files into one phonegap.js file.
This task does not create a compressed JavaScript file. -->
<target name="build-uncompressed-javascript">
<!-- Clean up existing files -->
<delete file="assets/www/phonegap.${version}.min.js"/>
<delete file="assets/www/phonegap-${version}.min.js"/>
<delete file="assets/www/phonegap-tmp.js"/>
<delete file="assets/www/phonegap.${version}.js"/>
<delete file="assets/www/phonegap-${version}.js"/>
<!-- Create uncompressed JS file -->
<concat destfile="assets/www/phonegap.${version}.js">
<concat destfile="assets/www/phonegap-${version}.js">
<fileset dir="assets/js" includes="phonegap.js.base" />
<fileset dir="assets/js" includes="*.js" />
</concat>
<!-- update project files to reference phonegap-x.x.x.js -->
<replaceregexp match="phonegap(.*)\.js" replace="phonegap.${version}.js" byline="true">
<replaceregexp match="phonegap(.*)\.js" replace="phonegap-${version}.js" byline="true">
<fileset file="assets/www/index.html" />
<fileset file="../example/index.html" />
</replaceregexp>
@@ -134,25 +137,28 @@
<delete file="assets/www/phonegap_${version}.js"/>
<!-- Create uncompressed JS file -->
<concat destfile="assets/www/phonegap.${version}.js">
<concat destfile="assets/www/phonegap-${version}.js">
<fileset dir="assets/js" includes="phonegap.js.base" />
<fileset dir="assets/js" includes="*.js" />
</concat>
<!-- Compress JS file -->
<java jar="${basedir}/../util/yuicompressor/yuicompressor-2.4.2.jar" fork="true" failonerror="true">
<arg line="--nomunge -o assets/www/phonegap-tmp.js assets/www/phonegap.${version}.js"/>
<arg line="--nomunge -o assets/www/phonegap-tmp.js assets/www/phonegap-${version}.js"/>
</java>
<concat destfile="assets/www/phonegap.${version}.min.js">
<concat destfile="assets/www/phonegap-${version}.min.js">
<fileset dir="assets/js" includes="header.txt" />
<fileset dir="assets/www" includes="phonegap-tmp.js" />
</concat>
<!-- update project files to reference phonegap-x.x.x.min.js -->
<replaceregexp match="phonegap(.*)\.js" replace="phonegap.${version}.min.js" byline="true">
<replaceregexp match="phonegap(.*)\.js" replace="phonegap-${version}.min.js" byline="true">
<fileset file="assets/www/index.html" />
<fileset file="../example/index.html" />
</replaceregexp>
<replaceregexp match="phonegapVersion = [\u0022].*[\u0022];" replace="phonegapVersion = ${dblQuote}${version}${dblQuote};" byline="true">
<fileset file="src/com/phonegap/Device.java" />
</replaceregexp>
<!-- Delete temp file -->
<delete file="assets/www/phonegap-tmp.js"/>
@@ -167,7 +173,7 @@
"build-javascript" => "build-uncompressed-javascript".
-->
<target name="jar" depends="build-javascript, compile">
<jar jarfile="phonegap.${version}.jar" basedir="bin/classes" excludes="com/phonegap/R.class,com/phonegap/R$*.class"/>
<jar jarfile="phonegap-${version}.jar" basedir="bin/classes" excludes="com/phonegap/R.class,com/phonegap/R$*.class"/>
</target>
<target name="phonegap_debug" depends="build-javascript, debug">

20
framework/res/xml/plugins.xml Executable file
View File

@@ -0,0 +1,20 @@
<!--?xml version="1.0" encoding="utf-8"?-->
<plugins>
<plugin name="App" value="com.phonegap.App"/>
<plugin name="Geolocation" value="com.phonegap.GeoBroker"/>
<plugin name="Device" value="com.phonegap.Device"/>
<plugin name="Accelerometer" value="com.phonegap.AccelListener"/>
<plugin name="Compass" value="com.phonegap.CompassListener"/>
<plugin name="Media" value="com.phonegap.AudioHandler"/>
<plugin name="Camera" value="com.phonegap.CameraLauncher"/>
<plugin name="Contacts" value="com.phonegap.ContactManager"/>
<plugin name="Crypto" value="com.phonegap.CryptoHandler"/>
<plugin name="File" value="com.phonegap.FileUtils"/>
<plugin name="Location" value="com.phonegap.GeoBroker"/>
<plugin name="Network Status" value="com.phonegap.NetworkManager"/>
<plugin name="Notification" value="com.phonegap.Notification"/>
<plugin name="Storage" value="com.phonegap.Storage"/>
<plugin name="Temperature" value="com.phonegap.TempListener"/>
<plugin name="FileTransfer" value="com.phonegap.FileTransfer"/>
<plugin name="Capture" value="com.phonegap.Capture"/>
</plugins>

View File

@@ -12,6 +12,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import java.util.HashMap;
/**
* This class exposes methods in DroidGap that can be called from JavaScript.
@@ -83,8 +84,11 @@ public class App extends Plugin {
public void loadUrl(String url, JSONObject props) throws JSONException {
System.out.println("App.loadUrl("+url+","+props+")");
int wait = 0;
boolean usePhoneGap = true;
boolean clearPrev = false;
// If there are properties, then set them on the Activity
HashMap<String, Object> params = new HashMap<String, Object>();
if (props != null) {
JSONArray keys = props.names();
for (int i=0; i<keys.length(); i++) {
@@ -92,31 +96,42 @@ public class App extends Plugin {
if (key.equals("wait")) {
wait = props.getInt(key);
}
else if (key.equalsIgnoreCase("usephonegap")) {
usePhoneGap = props.getBoolean(key);
}
else if (key.equalsIgnoreCase("clearprev")) {
clearPrev = props.getBoolean(key);
}
else {
Object value = props.get(key);
if (value == null) {
}
else if (value.getClass().equals(String.class)) {
this.ctx.getIntent().putExtra(key, (String)value);
params.put(key, (String)value);
}
else if (value.getClass().equals(Boolean.class)) {
this.ctx.getIntent().putExtra(key, (Boolean)value);
params.put(key, (Boolean)value);
}
else if (value.getClass().equals(Integer.class)) {
this.ctx.getIntent().putExtra(key, (Integer)value);
params.put(key, (Integer)value);
}
}
}
}
// If wait property, then delay loading
if (wait > 0) {
((DroidGap)this.ctx).loadUrl(url, wait);
}
else {
((DroidGap)this.ctx).loadUrl(url);
try {
synchronized(this) {
this.wait(wait);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
((DroidGap)this.ctx).showWebPage(url, usePhoneGap, clearPrev, params);
}
/**

View File

@@ -114,51 +114,65 @@ public abstract class ContactAccessor {
String key;
try {
for (int i=0; i<fields.length(); i++) {
key = fields.getString(i);
if (key.startsWith("displayName")) {
map.put("displayName", true);
}
else if (key.startsWith("name")) {
map.put("name", true);
}
else if (key.startsWith("nickname")) {
map.put("nickname", true);
}
else if (key.startsWith("phoneNumbers")) {
map.put("phoneNumbers", true);
}
else if (key.startsWith("emails")) {
map.put("emails", true);
}
else if (key.startsWith("addresses")) {
map.put("addresses", true);
}
else if (key.startsWith("ims")) {
map.put("ims", true);
}
else if (key.startsWith("organizations")) {
map.put("organizations", true);
}
else if (key.startsWith("birthday")) {
map.put("birthday", true);
}
else if (key.startsWith("anniversary")) {
map.put("anniversary", true);
}
else if (key.startsWith("note")) {
map.put("note", true);
}
else if (key.startsWith("relationships")) {
map.put("relationships", true);
}
else if (key.startsWith("urls")) {
map.put("urls", true);
}
else if (key.startsWith("photos")) {
map.put("photos", true);
}
}
if (fields.length() == 1 && fields.getString(0).equals("*")) {
map.put("displayName", true);
map.put("name", true);
map.put("nickname", true);
map.put("phoneNumbers", true);
map.put("emails", true);
map.put("addresses", true);
map.put("ims", true);
map.put("organizations", true);
map.put("birthday", true);
map.put("note", true);
map.put("urls", true);
map.put("photos", true);
map.put("categories", true);
}
else {
for (int i=0; i<fields.length(); i++) {
key = fields.getString(i);
if (key.startsWith("displayName")) {
map.put("displayName", true);
}
else if (key.startsWith("name")) {
map.put("name", true);
}
else if (key.startsWith("nickname")) {
map.put("nickname", true);
}
else if (key.startsWith("phoneNumbers")) {
map.put("phoneNumbers", true);
}
else if (key.startsWith("emails")) {
map.put("emails", true);
}
else if (key.startsWith("addresses")) {
map.put("addresses", true);
}
else if (key.startsWith("ims")) {
map.put("ims", true);
}
else if (key.startsWith("organizations")) {
map.put("organizations", true);
}
else if (key.startsWith("birthday")) {
map.put("birthday", true);
}
else if (key.startsWith("note")) {
map.put("note", true);
}
else if (key.startsWith("urls")) {
map.put("urls", true);
}
else if (key.startsWith("photos")) {
map.put("photos", true);
}
else if (key.startsWith("categories")) {
map.put("categories", true);
}
}
}
}
catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
@@ -196,13 +210,19 @@ public abstract class ContactAccessor {
* Handles adding a JSON Contact object into the database.
* @return TODO
*/
public abstract boolean save(JSONObject contact);
public abstract String save(JSONObject contact);
/**
* Handles searching through SDK-specific contacts API.
*/
public abstract JSONArray search(JSONArray filter, JSONObject options);
/**
* Handles searching through SDK-specific contacts API.
* @throws JSONException
*/
public abstract JSONObject getContactById(String id) throws JSONException;
/**
* Handles removing a contact from the database.
*/

View File

@@ -451,7 +451,7 @@ public class ContactAccessorSdk3_4 extends ContactAccessor {
* @returns true if the contact is successfully saved, false otherwise.
*/
@Override
public boolean save(JSONObject contact) {
public String save(JSONObject contact) {
ContentValues personValues = new ContentValues();
String id = getJsonString(contact, "id");
@@ -492,9 +492,9 @@ public class ContactAccessorSdk3_4 extends ContactAccessor {
saveEntries(contact, newPersonUri, "ims", Contacts.KIND_IM);
// Successfully create a Contact
return true;
return id;
}
return false;
return null;
}
/**
@@ -824,4 +824,10 @@ public class ContactAccessorSdk3_4 extends ContactAccessor {
return (result > 0) ? true : false;
}
@Override
public JSONObject getContactById(String id) throws JSONException {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -46,6 +46,7 @@ import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.OperationApplicationException;
@@ -88,7 +89,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
*/
private static final Map<String, String> dbMap = new HashMap<String, String>();
static {
dbMap.put("id", ContactsContract.Contacts._ID);
dbMap.put("id", ContactsContract.Data.CONTACT_ID);
dbMap.put("displayName", ContactsContract.Contacts.DISPLAY_NAME);
dbMap.put("name", ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
dbMap.put("name.formatted", ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
@@ -115,14 +116,12 @@ public class ContactAccessorSdk5 extends ContactAccessor {
dbMap.put("organizations.name", ContactsContract.CommonDataKinds.Organization.COMPANY);
dbMap.put("organizations.department", ContactsContract.CommonDataKinds.Organization.DEPARTMENT);
dbMap.put("organizations.title", ContactsContract.CommonDataKinds.Organization.TITLE);
//dbMap.put("revision", null);
dbMap.put("birthday", ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
dbMap.put("note", ContactsContract.CommonDataKinds.Note.NOTE);
dbMap.put("photos.value", ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
//dbMap.put("categories.value", null);
dbMap.put("urls", ContactsContract.CommonDataKinds.Website.URL);
dbMap.put("urls.value", ContactsContract.CommonDataKinds.Website.URL);
//dbMap.put("timezone", null);
}
/**
@@ -142,9 +141,6 @@ public class ContactAccessorSdk5 extends ContactAccessor {
*/
@Override
public JSONArray search(JSONArray fields, JSONObject options) {
long totalEnd;
long totalStart = System.currentTimeMillis();
// Get the find options
String searchTerm = "";
int limit = Integer.MAX_VALUE;
@@ -180,7 +176,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
// Build the ugly where clause and where arguments for one big query.
WhereOptions whereOptions = buildWhereClause(fields, searchTerm);
// Get all the id's where the search term matches the fields passed in.
Cursor idCursor = mApp.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
new String[] { ContactsContract.Data.CONTACT_ID },
@@ -206,8 +202,49 @@ public class ContactAccessorSdk5 extends ContactAccessor {
idOptions.getWhereArgs(),
ContactsContract.Data.CONTACT_ID + " ASC");
//Log.d(LOG_TAG, "Cursor length = " + c.getCount());
JSONArray contacts = populateContactArray(limit, populate, c);
return contacts;
}
/**
* A special search that finds one contact by id
*
* @param id contact to find by id
* @return a JSONObject representing the contact
* @throws JSONException
*/
public JSONObject getContactById(String id) throws JSONException {
// Do the id query
Cursor c = mApp.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID + " = ? ",
new String[] { id },
ContactsContract.Data.CONTACT_ID + " ASC");
JSONArray fields = new JSONArray();
fields.put("*");
HashMap<String,Boolean> populate = buildPopulationSet(fields);
JSONArray contacts = populateContactArray(1, populate, c);
if (contacts.length() == 1) {
return contacts.getJSONObject(0);
} else {
return null;
}
}
/**
* Creates an array of contacts from the cursor you pass in
*
* @param limit max number of contacts for the array
* @param populate whether or not you should populate a certain value
* @param c the cursor
* @return a JSONArray of contacts
*/
private JSONArray populateContactArray(int limit,
HashMap<String, Boolean> populate, Cursor c) {
String contactId = "";
String rawId = "";
@@ -264,16 +301,18 @@ public class ContactAccessorSdk5 extends ContactAccessor {
newContact = false;
contact.put("id", contactId);
contact.put("rawId", rawId);
contact.put("displayName", c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME)));
}
// Grab the mimetype of the current row as it will be used in a lot of comparisons
mimetype = c.getString(c.getColumnIndex(ContactsContract.Data.MIMETYPE));
if (mimetype.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
&& isRequired("name",populate)) {
contact.put("name", nameQuery(c));
}
if (mimetype.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
contact.put("displayName", c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME)));
}
if (mimetype.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
&& isRequired("name",populate)) {
contact.put("name", nameQuery(c));
}
else if (mimetype.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
&& isRequired("phoneNumbers",populate)) {
phones.put(phoneQuery(c));
@@ -332,12 +371,8 @@ public class ContactAccessorSdk5 extends ContactAccessor {
}
}
c.close();
totalEnd = System.currentTimeMillis();
Log.d(LOG_TAG,"Total time = " + (totalEnd-totalStart));
return contacts;
}
return contacts;
}
/**
* Builds a where clause all all the ids passed into the method
@@ -416,15 +451,67 @@ public class ContactAccessorSdk5 extends ContactAccessor {
ArrayList<String> whereArgs = new ArrayList<String>();
WhereOptions options = new WhereOptions();
/*
* Special case where the user wants all fields returned
*/
if (isWildCardSearch(fields)) {
// Get all contacts with all properties
if ("%".equals(searchTerm)) {
options.setWhere("(" + ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? )");
options.setWhereArgs(new String[] {searchTerm});
return options;
} else {
// Get all contacts that match the filter but return all properties
where.add("(" + dbMap.get("displayName") + " LIKE ? )");
whereArgs.add(searchTerm);
where.add("(" + dbMap.get("name") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("nickname") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("phoneNumbers") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("emails") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("addresses") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("ims") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("organizations") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("note") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE);
where.add("(" + dbMap.get("urls") + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
whereArgs.add(searchTerm);
whereArgs.add(ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE);
}
}
/*
* Special case for when the user wants all the contacts
* Special case for when the user wants all the contacts but
*/
if ("%".equals(searchTerm)) {
options.setWhere("(" + ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? )");
options.setWhereArgs(new String[] {searchTerm});
return options;
}
}
String key;
try {
@@ -432,10 +519,14 @@ public class ContactAccessorSdk5 extends ContactAccessor {
for (int i=0; i<fields.length(); i++) {
key = fields.getString(i);
if (key.startsWith("displayName")) {
where.add("(" + dbMap.get(key) + " LIKE ? )");
whereArgs.add(searchTerm);
}
if (key.equals("id")) {
where.add("(" + dbMap.get(key) + " = ? )");
whereArgs.add(searchTerm.substring(1, searchTerm.length()-1));
}
else if (key.startsWith("displayName")) {
where.add("(" + dbMap.get(key) + " LIKE ? )");
whereArgs.add(searchTerm);
}
else if (key.startsWith("name")) {
where.add("(" + dbMap.get(key) + " LIKE ? AND "
+ ContactsContract.Data.MIMETYPE + " = ? )");
@@ -521,6 +612,26 @@ public class ContactAccessorSdk5 extends ContactAccessor {
}
/**
* If the user passes in the '*' wildcard character for search then they want all fields for each contact
*
* @param fields
* @return true if wildcard search requested, false otherwise
*/
private boolean isWildCardSearch(JSONArray fields) {
// Only do a wildcard search if we are passed ["*"]
if (fields.length() == 1) {
try {
if ("*".equals(fields.getString(0))) {
return true;
}
} catch (JSONException e) {
return false;
}
}
return false;
}
/**
* Create a ContactOrganization JSONObject
* @param cursor the current database row
* @return a JSONObject representing a ContactOrganization
@@ -529,6 +640,8 @@ public class ContactAccessorSdk5 extends ContactAccessor {
JSONObject organization = new JSONObject();
try {
organization.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization._ID)));
organization.put("pref", false); // Android does not store pref attribute
organization.put("type", getOrgType(cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TYPE))));
organization.put("department", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.DEPARTMENT)));
organization.put("name", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.COMPANY)));
organization.put("title", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE)));
@@ -547,6 +660,8 @@ public class ContactAccessorSdk5 extends ContactAccessor {
JSONObject address = new JSONObject();
try {
address.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal._ID)));
address.put("pref", false); // Android does not store pref attribute
address.put("type", getAddressType(cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TYPE))));
address.put("formatted", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS)));
address.put("streetAddress", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET)));
address.put("locality", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY)));
@@ -693,9 +808,9 @@ public class ContactAccessorSdk5 extends ContactAccessor {
* This method will save a contact object into the devices contacts database.
*
* @param contact the contact to be saved.
* @returns true if the contact is successfully saved, false otherwise.
* @returns the id if the contact is successfully saved, null otherwise.
*/
public boolean save(JSONObject contact) {
public String save(JSONObject contact) {
AccountManager mgr = AccountManager.get(mApp);
Account[] accounts = mgr.getAccounts();
Account account = null;
@@ -730,8 +845,9 @@ public class ContactAccessorSdk5 extends ContactAccessor {
}
}
if(account == null)
return false;
if(account == null) {
return null;
}
String id = getJsonString(contact, "id");
// Create new contact
@@ -751,7 +867,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
* @param contact the contact to be saved
* @param account the account to be saved under
*/
private boolean modifyContact(String id, JSONObject contact, Account account) {
private String modifyContact(String id, JSONObject contact, Account account) {
// Get the RAW_CONTACT_ID which is needed to insert new values in an already existing contact.
// But not needed to update existing values.
int rawId = (new Integer(getJsonString(contact,"rawId"))).intValue();
@@ -892,6 +1008,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
ContentValues contentValues = new ContentValues();
contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId);
contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE);
contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, getAddressType(getJsonString(address, "type")));
contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, getJsonString(address, "formatted"));
contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.STREET, getJsonString(address, "streetAddress"));
contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.CITY, getJsonString(address, "locality"));
@@ -908,6 +1025,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
.withSelection(ContactsContract.CommonDataKinds.StructuredPostal._ID + "=? AND " +
ContactsContract.Data.MIMETYPE + "=?",
new String[]{addressId, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE})
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, getAddressType(getJsonString(address, "type")))
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, getJsonString(address, "formatted"))
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, getJsonString(address, "streetAddress"))
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, getJsonString(address, "locality"))
@@ -936,6 +1054,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
ContentValues contentValues = new ContentValues();
contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId);
contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
contentValues.put(ContactsContract.CommonDataKinds.Organization.TYPE, getOrgType(getJsonString(org, "type")));
contentValues.put(ContactsContract.CommonDataKinds.Organization.DEPARTMENT, getJsonString(org, "department"));
contentValues.put(ContactsContract.CommonDataKinds.Organization.COMPANY, getJsonString(org, "name"));
contentValues.put(ContactsContract.CommonDataKinds.Organization.TITLE, getJsonString(org, "title"));
@@ -949,6 +1068,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
.withSelection(ContactsContract.CommonDataKinds.Organization._ID + "=? AND " +
ContactsContract.Data.MIMETYPE + "=?",
new String[]{orgId, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE})
.withValue(ContactsContract.CommonDataKinds.Organization.TYPE, getOrgType(getJsonString(org, "type")))
.withValue(ContactsContract.CommonDataKinds.Organization.DEPARTMENT, getJsonString(org, "department"))
.withValue(ContactsContract.CommonDataKinds.Organization.COMPANY, getJsonString(org, "name"))
.withValue(ContactsContract.CommonDataKinds.Organization.TITLE, getJsonString(org, "title"))
@@ -1107,7 +1227,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
//Modify contact
try {
mApp.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
mApp.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
Log.e(LOG_TAG, e.getMessage(), e);
Log.e(LOG_TAG, Log.getStackTraceString(e), e);
@@ -1118,7 +1238,12 @@ public class ContactAccessorSdk5 extends ContactAccessor {
retVal = false;
}
return retVal;
// if the save was a succes return the contact ID
if (retVal) {
return id;
} else {
return null;
}
}
/**
@@ -1163,7 +1288,8 @@ public class ContactAccessorSdk5 extends ContactAccessor {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Organization.DEPARTMENT, getJsonString(org, "department"))
.withValue(ContactsContract.CommonDataKinds.Organization.TYPE, getOrgType(getJsonString(org, "type")))
.withValue(ContactsContract.CommonDataKinds.Organization.DEPARTMENT, getJsonString(org, "department"))
.withValue(ContactsContract.CommonDataKinds.Organization.COMPANY, getJsonString(org, "name"))
.withValue(ContactsContract.CommonDataKinds.Organization.TITLE, getJsonString(org, "title"))
.build());
@@ -1180,6 +1306,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, getAddressType(getJsonString(address, "type")))
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, getJsonString(address, "formatted"))
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, getJsonString(address, "streetAddress"))
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, getJsonString(address, "locality"))
@@ -1294,7 +1421,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
* @param contact the contact to be saved
* @param account the account to be saved under
*/
private boolean createNewContact(JSONObject contact, Account account) {
private String createNewContact(JSONObject contact, Account account) {
// Create a list of attributes to add to the contact database
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
@@ -1461,18 +1588,21 @@ public class ContactAccessorSdk5 extends ContactAccessor {
Log.d(LOG_TAG, "Could not get photos");
}
boolean retVal = true;
String newId = null;
//Add contact
try {
mApp.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
ContentProviderResult[] cpResults = mApp.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
if (cpResults.length >= 0) {
newId = cpResults[0].uri.getLastPathSegment();
}
} catch (RemoteException e) {
Log.e(LOG_TAG, e.getMessage(), e);
retVal = false;
newId = null;
} catch (OperationApplicationException e) {
Log.e(LOG_TAG, e.getMessage(), e);
retVal = false;
newId = null;
}
return retVal;
return newId;
}
@Override
@@ -1643,58 +1773,144 @@ public class ContactAccessorSdk5 extends ContactAccessor {
return stringType;
}
/**
* Converts a string from the W3C Contact API to it's Android int value.
* @param string
* @return Android int value
*/
private int getContactType(String string) {
int type = ContactsContract.CommonDataKinds.Email.TYPE_OTHER;
if (string!=null) {
if ("home".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_HOME;
}
else if ("work".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_WORK;
}
else if ("other".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_OTHER;
}
else if ("mobile".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_MOBILE;
}
else if ("custom".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM;
}
}
return type;
}
/**
* Converts a string from the W3C Contact API to it's Android int value.
* @param string
* @return Android int value
*/
private int getContactType(String string) {
int type = ContactsContract.CommonDataKinds.Email.TYPE_OTHER;
if (string!=null) {
if ("home".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_HOME;
}
else if ("work".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_WORK;
}
else if ("other".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_OTHER;
}
else if ("mobile".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_MOBILE;
}
else if ("custom".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM;
}
}
return type;
}
/**
* getPhoneType converts an Android phone type into a string
* @param type
* @return phone type as string.
*/
private String getContactType(int type) {
String stringType;
switch (type) {
case ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM:
stringType = "custom";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_HOME:
stringType = "home";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_WORK:
stringType = "work";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_MOBILE:
stringType = "mobile";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_OTHER:
default:
stringType = "other";
break;
}
return stringType;
}
/**
* getPhoneType converts an Android phone type into a string
* @param type
* @return phone type as string.
*/
private String getContactType(int type) {
String stringType;
switch (type) {
case ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM:
stringType = "custom";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_HOME:
stringType = "home";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_WORK:
stringType = "work";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_MOBILE:
stringType = "mobile";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_OTHER:
default:
stringType = "other";
break;
}
return stringType;
}
/**
* Converts a string from the W3C Contact API to it's Android int value.
* @param string
* @return Android int value
*/
private int getOrgType(String string) {
int type = ContactsContract.CommonDataKinds.Organization.TYPE_OTHER;
if (string!=null) {
if ("work".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Organization.TYPE_WORK;
}
else if ("other".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Organization.TYPE_OTHER;
}
else if ("custom".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.Organization.TYPE_CUSTOM;
}
}
return type;
}
/**
* getPhoneType converts an Android phone type into a string
* @param type
* @return phone type as string.
*/
private String getOrgType(int type) {
String stringType;
switch (type) {
case ContactsContract.CommonDataKinds.Organization.TYPE_CUSTOM:
stringType = "custom";
break;
case ContactsContract.CommonDataKinds.Organization.TYPE_WORK:
stringType = "work";
break;
case ContactsContract.CommonDataKinds.Organization.TYPE_OTHER:
default:
stringType = "other";
break;
}
return stringType;
}
/**
* Converts a string from the W3C Contact API to it's Android int value.
* @param string
* @return Android int value
*/
private int getAddressType(String string) {
int type = ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER;
if (string!=null) {
if ("work".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK;
}
else if ("other".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER;
}
else if ("home".equals(string.toLowerCase())) {
return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME;
}
}
return type;
}
/**
* getPhoneType converts an Android phone type into a string
* @param type
* @return phone type as string.
*/
private String getAddressType(int type) {
String stringType;
switch (type) {
case ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME:
stringType = "home";
break;
case ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK:
stringType = "work";
break;
case ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER:
default:
stringType = "other";
break;
}
return stringType;
}
}

View File

@@ -43,29 +43,26 @@ public class ContactManager extends Plugin {
try {
if (action.equals("search")) {
JSONArray res = contactAccessor.search(args.getJSONArray(0), args.optJSONObject(1));
return new PluginResult(status, res, "navigator.service.contacts.cast");
return new PluginResult(status, res, "navigator.contacts.cast");
}
else if (action.equals("save")) {
if (contactAccessor.save(args.getJSONObject(0))) {
return new PluginResult(status, result);
}
else {
JSONObject r = new JSONObject();
r.put("code", 0);
return new PluginResult(PluginResult.Status.ERROR, r);
String id = contactAccessor.save(args.getJSONObject(0));
if (id != null) {
JSONObject res = contactAccessor.getContactById(id);
if (res != null) {
return new PluginResult(status, res);
}
}
}
else if (action.equals("remove")) {
if (contactAccessor.remove(args.getString(0))) {
return new PluginResult(status, result);
}
else {
JSONObject r = new JSONObject();
r.put("code", 2);
return new PluginResult(PluginResult.Status.ERROR, r);
}
}
return new PluginResult(status, result);
// If we get to this point an error has occurred
JSONObject r = new JSONObject();
r.put("code", 0);
return new PluginResult(PluginResult.Status.ERROR, r);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);

2
framework/src/com/phonegap/Device.java Executable file → Normal file
View File

@@ -18,7 +18,7 @@ import android.provider.Settings;
public class Device extends Plugin {
public static String phonegapVersion = "0.9.5"; // PhoneGap version
public static String phonegapVersion = "1.0.0rc1"; // PhoneGap version
public static String platform = "Android"; // Device OS
public static String uuid; // Device UUID

View File

@@ -7,11 +7,15 @@
*/
package com.phonegap;
import java.util.HashMap;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -46,7 +50,7 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import com.phonegap.api.PhonegapActivity;
import com.phonegap.api.Plugin;
import com.phonegap.api.IPlugin;
import com.phonegap.api.PluginManager;
/**
@@ -91,10 +95,6 @@ import com.phonegap.api.PluginManager;
* // (String - default=null)
* super.setStringProperty("loadingDialog", "Wait,Loading Demo...");
*
* // Hide loadingDialog when page loaded instead of when deviceready event
* // occurs. (Boolean - default=false)
* super.setBooleanProperty("hideLoadingDialogOnPage", true);
*
* // Cause all links on web page to be loaded into existing web view,
* // instead of being loaded into new browser. (Boolean - default=false)
* super.setBooleanProperty("loadInWebView", true);
@@ -126,20 +126,19 @@ public class DroidGap extends PhonegapActivity {
protected PluginManager pluginManager;
protected boolean cancelLoadUrl = false;
protected boolean clearHistory = false;
protected ProgressDialog spinnerDialog = null;
// The initial URL for our app
// ie http://server/path/index.html#abc?query
private String url;
// The initial URL for our app up to and including the file name
// ie http://server/path/index.html
private String urlFile;
// The base of the initial URL for our app
private String baseUrl;
// The base of the initial URL for our app.
// Does not include file name. Ends with /
// ie http://server/path/
private String baseUrl = null;
// Plugin to call when activity result is received
protected Plugin activityResultCallback = null;
protected IPlugin activityResultCallback = null;
protected boolean activityResultKeepRunning;
// Flag indicates that a loadUrl timeout occurred
@@ -148,10 +147,6 @@ public class DroidGap extends PhonegapActivity {
/*
* The variables below are used to cache some of the activity properties.
*/
// Flag indicates that "app loading" dialog should be hidden once page is loaded.
// The default is to hide it once PhoneGap JavaScript code has initialized.
protected boolean hideLoadingDialogOnPageLoad = false;
// Flag indicates that a URL navigated to from PhoneGap app should be loaded into same webview
// instead of being loaded into the web browser.
@@ -289,23 +284,6 @@ public class DroidGap extends PhonegapActivity {
this.callbackServer = new CallbackServer();
this.pluginManager = new PluginManager(appView, this);
this.addService("App", "com.phonegap.App");
this.addService("Geolocation", "com.phonegap.GeoBroker");
this.addService("Device", "com.phonegap.Device");
this.addService("Accelerometer", "com.phonegap.AccelListener");
this.addService("Compass", "com.phonegap.CompassListener");
this.addService("Media", "com.phonegap.AudioHandler");
this.addService("Camera", "com.phonegap.CameraLauncher");
this.addService("Contacts", "com.phonegap.ContactManager");
this.addService("Crypto", "com.phonegap.CryptoHandler");
this.addService("File", "com.phonegap.FileUtils");
this.addService("Location", "com.phonegap.GeoBroker"); // Always add Location, even though it is built-in on 2.x devices. Let JavaScript decide which one to use.
this.addService("Network Status", "com.phonegap.NetworkManager");
this.addService("Notification", "com.phonegap.Notification");
this.addService("Storage", "com.phonegap.Storage");
this.addService("Temperature", "com.phonegap.TempListener");
this.addService("FileTransfer", "com.phonegap.FileTransfer");
this.addService("Capture", "com.phonegap.Capture");
}
/**
@@ -325,9 +303,6 @@ public class DroidGap extends PhonegapActivity {
root.setBackgroundResource(this.splashscreen);
}
// If hideLoadingDialogOnPageLoad
this.hideLoadingDialogOnPageLoad = this.getBooleanProperty("hideLoadingDialogOnPageLoad", false);
// If loadInWebView
this.loadInWebView = this.getBooleanProperty("loadInWebView", false);
@@ -348,14 +323,15 @@ public class DroidGap extends PhonegapActivity {
*/
public void loadUrl(final String url) {
System.out.println("loadUrl("+url+")");
this.urlFile = this.getUrlFile(url);
this.url = url;
int i = url.lastIndexOf('/');
if (i > 0) {
this.baseUrl = url.substring(0, i);
}
else {
this.baseUrl = this.url;
if (this.baseUrl == null) {
int i = url.lastIndexOf('/');
if (i > 0) {
this.baseUrl = url.substring(0, i+1);
}
else {
this.baseUrl = this.url + "/";
}
}
System.out.println("url="+url+" baseUrl="+baseUrl);
@@ -388,10 +364,7 @@ public class DroidGap extends PhonegapActivity {
message = loading;
}
}
JSONArray parm = new JSONArray();
parm.put(title);
parm.put(message);
me.pluginManager.exec("Notification", "activityStart", null, parm.toString(), false);
me.spinnerStart(title, message);
}
// Create a timeout timer for loadUrl
@@ -613,7 +586,7 @@ public class DroidGap extends PhonegapActivity {
public void setDoubleProperty(String name, double value) {
this.getIntent().putExtra(name, value);
}
@Override
/**
* Called when the system is about to start resuming a previous activity.
@@ -723,20 +696,88 @@ public class DroidGap extends PhonegapActivity {
this.callbackServer.sendJavascript(statement);
}
/**
* Return up to file part of url.
* If url = http://server/page.html#abc, then return http://server/page.html
* Display a new browser with the specified URL.
*
* @param url
* @return
* NOTE: If usePhoneGap is set, only trusted PhoneGap URLs should be loaded,
* since any PhoneGap API can be called by the loaded HTML page.
*
* @param url The url to load.
* @param usePhoneGap Load url in PhoneGap webview.
* @param clearPrev Clear the activity stack, so new app becomes top of stack
* @param params DroidGap parameters for new app
* @throws android.content.ActivityNotFoundException
*/
private String getUrlFile(String url) {
int p1 = url.indexOf("#");
int p2 = url.indexOf("?");
if (p1 < 0) p1 = url.length();
if (p2 < 0) p2 = url.length();
int p3 = (p1 < p2) ? p1 : p2;
return url.substring(0, p3);
public void showWebPage(String url, boolean usePhoneGap, boolean clearPrev, HashMap<String, Object> params) throws android.content.ActivityNotFoundException {
Intent intent = null;
if (usePhoneGap) {
intent = new Intent().setClass(this, com.phonegap.DroidGap.class);
intent.putExtra("url", url);
// Add parameters
if (params != null) {
java.util.Set<Entry<String,Object>> s = params.entrySet();
java.util.Iterator<Entry<String,Object>> it = s.iterator();
while(it.hasNext()) {
Entry<String,Object> entry = it.next();
String key = entry.getKey();
Object value = entry.getValue();
if (value == null) {
}
else if (value.getClass().equals(String.class)) {
intent.putExtra(key, (String)value);
}
else if (value.getClass().equals(Boolean.class)) {
intent.putExtra(key, (Boolean)value);
}
else if (value.getClass().equals(Integer.class)) {
intent.putExtra(key, (Integer)value);
}
}
}
}
else {
intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
}
this.startActivity(intent);
// Finish current activity
if (clearPrev) {
this.finish();
}
}
/**
* Show the spinner. Must be called from the UI thread.
*
* @param title Title of the dialog
* @param message The message of the dialog
*/
public void spinnerStart(final String title, final String message) {
if (this.spinnerDialog != null) {
this.spinnerDialog.dismiss();
this.spinnerDialog = null;
}
final DroidGap me = this;
this.spinnerDialog = ProgressDialog.show(DroidGap.this, title , message, true, true,
new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
me.spinnerDialog = null;
}
});
}
/**
* Stop spinner.
*/
public void spinnerStop() {
if (this.spinnerDialog != null) {
this.spinnerDialog.dismiss();
this.spinnerDialog = null;
}
}
/**
@@ -825,8 +866,11 @@ public class DroidGap extends PhonegapActivity {
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
// Security check to make sure any requests are coming from the page initially
// loaded in webview and not another loaded in an iframe.
boolean reqOk = false;
if (this.ctx.urlFile.equals(this.ctx.getUrlFile(url))) {
if (url.indexOf(this.ctx.baseUrl) == 0) {
reqOk = true;
}
@@ -1069,17 +1113,17 @@ public class DroidGap extends PhonegapActivity {
// All else
else {
int i = url.lastIndexOf('/');
String newBaseUrl = url;
if (i > 0) {
newBaseUrl = url.substring(0, i);
}
// If our app or file:, then load into our webview
// NOTE: This replaces our app with new URL. When BACK is pressed,
// our app is reloaded and restarted. All state is lost.
if (this.ctx.loadInWebView || url.startsWith("file://") || this.ctx.baseUrl.equals(newBaseUrl)) {
this.ctx.appView.loadUrl(url);
if (this.ctx.loadInWebView || url.startsWith("file://") || url.indexOf(this.ctx.baseUrl) == 0) {
try {
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("loadingDialog", "");
this.ctx.showWebPage(url, true, false, params);
} catch (android.content.ActivityNotFoundException e) {
System.out.println("Error loading url into DroidGap - "+url+":"+ e.toString());
}
}
// If not our application, let default viewer handle
@@ -1120,10 +1164,7 @@ public class DroidGap extends PhonegapActivity {
appView.setVisibility(View.VISIBLE);
// Stop "app loading" spinner if showing
if (this.ctx.hideLoadingDialogOnPageLoad) {
this.ctx.hideLoadingDialogOnPageLoad = false;
this.ctx.pluginManager.exec("Notification", "activityStop", null, "[]", false);
}
this.ctx.spinnerStop();
// Clear history, so that previous screen isn't there when Back button is pressed
if (this.ctx.clearHistory) {
@@ -1250,12 +1291,7 @@ public class DroidGap extends PhonegapActivity {
@Override
public void startActivityForResult(Intent intent, int requestCode) throws RuntimeException {
System.out.println("startActivityForResult(intent,"+requestCode+")");
if (requestCode == -1) {
super.startActivityForResult(intent, requestCode);
}
else {
throw new RuntimeException("PhoneGap Exception: Call startActivityForResult(Command, Intent) instead.");
}
super.startActivityForResult(intent, requestCode);
}
/**
@@ -1266,7 +1302,7 @@ public class DroidGap extends PhonegapActivity {
* @param intent The intent to start
* @param requestCode The request code that is passed to callback to identify the activity
*/
public void startActivityForResult(Plugin command, Intent intent, int requestCode) {
public void startActivityForResult(IPlugin command, Intent intent, int requestCode) {
this.activityResultCallback = command;
this.activityResultKeepRunning = this.keepRunning;
@@ -1291,12 +1327,17 @@ public class DroidGap extends PhonegapActivity {
*/
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Plugin callback = this.activityResultCallback;
IPlugin callback = this.activityResultCallback;
if (callback != null) {
callback.onActivityResult(requestCode, resultCode, intent);
}
}
@Override
public void setActivityResultCallback(IPlugin plugin) {
this.activityResultCallback = plugin;
}
/**
* Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable).
* The errorCode parameter corresponds to one of the ERROR_* constants.

View File

@@ -66,6 +66,11 @@ public interface IPlugin {
*/
void onResume(boolean multitasking);
/**
* Called when the activity receives a new intent.
*/
void onNewIntent(Intent intent);
/**
* The final call you receive before your activity is destroyed.
*/

View File

@@ -15,7 +15,7 @@ import android.content.Intent;
* It is used to isolate plugin development, and remove dependency on entire Phonegap library.
*/
public abstract class PhonegapActivity extends Activity {
/**
* Add a class that implements a service.
*
@@ -39,5 +39,12 @@ public abstract class PhonegapActivity extends Activity {
* @param intent The intent to start
* @param requestCode The request code that is passed to callback to identify the activity
*/
abstract public void startActivityForResult(Plugin command, Intent intent, int requestCode);
abstract public void startActivityForResult(IPlugin command, Intent intent, int requestCode);
/**
* Set the plugin to be called when a sub-activity exits.
*
* @param plugin The plugin on which onActivityResult is to be called
*/
abstract public void setActivityResultCallback(IPlugin plugin);
}

View File

@@ -8,6 +8,7 @@
package com.phonegap.api;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Intent;
import android.webkit.WebView;
@@ -19,6 +20,7 @@ import android.webkit.WebView;
*/
public abstract class Plugin implements IPlugin {
public String id;
public WebView webView; // WebView object
public PhonegapActivity ctx; // PhonegapActivity object
@@ -126,6 +128,26 @@ public abstract class Plugin implements IPlugin {
this.ctx.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
}
/**
* Helper for success callbacks that just returns the Status.OK by default
*
* @param message The message to add to the success result.
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void success(JSONObject message, String callbackId) {
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId));
}
/**
* Helper for success callbacks that just returns the Status.OK by default
*
* @param message The message to add to the success result.
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void success(String message, String callbackId) {
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId));
}
/**
* Call the JavaScript error callback for this plugin.
*
@@ -135,4 +157,24 @@ public abstract class Plugin implements IPlugin {
public void error(PluginResult pluginResult, String callbackId) {
this.ctx.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
}
/**
* Helper for error callbacks that just returns the Status.ERROR by default
*
* @param message The message to add to the error result.
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void error(JSONObject message, String callbackId) {
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId));
}
/**
* Helper for error callbacks that just returns the Status.ERROR by default
*
* @param message The message to add to the error result.
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void error(String message, String callbackId) {
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId));
}
}

View File

@@ -7,13 +7,16 @@
*/
package com.phonegap.api;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException;
import org.xmlpull.v1.XmlPullParserException;
import android.content.Intent;
import android.content.res.XmlResourceParser;
import android.webkit.WebView;
/**
@@ -24,7 +27,7 @@ import android.webkit.WebView;
*/
public final class PluginManager {
private HashMap<String, Plugin> plugins = new HashMap<String,Plugin>();
private HashMap<String, IPlugin> plugins = new HashMap<String,IPlugin>();
private HashMap<String, String> services = new HashMap<String,String>();
private final PhonegapActivity ctx;
@@ -39,6 +42,33 @@ public final class PluginManager {
public PluginManager(WebView app, PhonegapActivity ctx) {
this.ctx = ctx;
this.app = app;
this.loadPlugins();
}
/**
* Load plugins from res/xml/plugins.xml
*/
public void loadPlugins() {
XmlResourceParser xml = ctx.getResources().getXml(com.phonegap.R.xml.plugins);
int eventType = -1;
while (eventType != XmlResourceParser.END_DOCUMENT) {
if (eventType == XmlResourceParser.START_TAG) {
String strNode = xml.getName();
if (strNode.equals("plugin")) {
String name = xml.getAttributeValue(null, "name");
String value = xml.getAttributeValue(null, "value");
System.out.println("Plugin: "+name+" => "+value);
this.addService(name, value);
}
}
try {
eventType = xml.next();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
@@ -75,7 +105,7 @@ public final class PluginManager {
c = getClassByName(clazz);
}
if (isPhoneGapPlugin(c)) {
final Plugin plugin = this.addPlugin(clazz, c);
final IPlugin plugin = this.addPlugin(clazz, c);
final PhonegapActivity ctx = this.ctx;
runAsync = async && !plugin.isSynch(action);
if (runAsync) {
@@ -101,7 +131,7 @@ public final class PluginManager {
ctx.sendJavascript(cr.toErrorCallbackString(callbackId));
}
} catch (Exception e) {
PluginResult cr = new PluginResult(PluginResult.Status.ERROR);
PluginResult cr = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
ctx.sendJavascript(cr.toErrorCallbackString(callbackId));
}
}
@@ -160,24 +190,7 @@ public final class PluginManager {
}
return false;
}
/**
* Add plugin to be loaded and cached. This creates an instance of the plugin.
* If plugin is already created, then just return it.
*
* @param className The class to load
* @return The plugin
*/
public Plugin addPlugin(String className) {
try {
return this.addPlugin(className, this.getClassByName(className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("Error adding plugin "+className+".");
}
return null;
}
/**
* Add plugin to be loaded and cached. This creates an instance of the plugin.
* If plugin is already created, then just return it.
@@ -188,12 +201,12 @@ public final class PluginManager {
* @return The plugin
*/
@SuppressWarnings("unchecked")
private Plugin addPlugin(String className, Class clazz) {
private IPlugin addPlugin(String className, Class clazz) {
if (this.plugins.containsKey(className)) {
return this.getPlugin(className);
}
try {
Plugin plugin = (Plugin)clazz.newInstance();
IPlugin plugin = (IPlugin)clazz.newInstance();
this.plugins.put(className, plugin);
plugin.setContext(this.ctx);
plugin.setView(this.app);
@@ -212,8 +225,8 @@ public final class PluginManager {
* @param className The class of the loaded plugin.
* @return
*/
private Plugin getPlugin(String className) {
Plugin plugin = this.plugins.get(className);
private IPlugin getPlugin(String className) {
IPlugin plugin = this.plugins.get(className);
return plugin;
}
@@ -234,11 +247,11 @@ public final class PluginManager {
* @param multitasking Flag indicating if multitasking is turned on for app
*/
public void onPause(boolean multitasking) {
java.util.Set<Entry<String,Plugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,Plugin>> it = s.iterator();
java.util.Set<Entry<String,IPlugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,IPlugin>> it = s.iterator();
while(it.hasNext()) {
Entry<String,Plugin> entry = it.next();
Plugin plugin = entry.getValue();
Entry<String,IPlugin> entry = it.next();
IPlugin plugin = entry.getValue();
plugin.onPause(multitasking);
}
}
@@ -249,11 +262,11 @@ public final class PluginManager {
* @param multitasking Flag indicating if multitasking is turned on for app
*/
public void onResume(boolean multitasking) {
java.util.Set<Entry<String,Plugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,Plugin>> it = s.iterator();
java.util.Set<Entry<String,IPlugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,IPlugin>> it = s.iterator();
while(it.hasNext()) {
Entry<String,Plugin> entry = it.next();
Plugin plugin = entry.getValue();
Entry<String,IPlugin> entry = it.next();
IPlugin plugin = entry.getValue();
plugin.onResume(multitasking);
}
}
@@ -262,11 +275,11 @@ public final class PluginManager {
* The final call you receive before your activity is destroyed.
*/
public void onDestroy() {
java.util.Set<Entry<String,Plugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,Plugin>> it = s.iterator();
java.util.Set<Entry<String,IPlugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,IPlugin>> it = s.iterator();
while(it.hasNext()) {
Entry<String,Plugin> entry = it.next();
Plugin plugin = entry.getValue();
Entry<String,IPlugin> entry = it.next();
IPlugin plugin = entry.getValue();
plugin.onDestroy();
}
}
@@ -275,11 +288,11 @@ public final class PluginManager {
* Called when the activity receives a new intent.
*/
public void onNewIntent(Intent intent) {
java.util.Set<Entry<String,Plugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,Plugin>> it = s.iterator();
java.util.Set<Entry<String,IPlugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,IPlugin>> it = s.iterator();
while(it.hasNext()) {
Entry<String,Plugin> entry = it.next();
Plugin plugin = entry.getValue();
Entry<String,IPlugin> entry = it.next();
IPlugin plugin = entry.getValue();
plugin.onNewIntent(intent);
}
}

View File

@@ -88,15 +88,18 @@ class Classic
# copies stuff from src directory into the android project directory (@path)
def copy_libs
version = IO.read(File.join(@framework_dir, '../VERSION'))
version = IO.read(File.join(@framework_dir, '../VERSION')).lstrip.rstrip
framework_res_dir = File.join(@framework_dir, "res")
app_res_dir = File.join(@path, "res")
# copies in the jar
FileUtils.mkdir_p File.join(@path, "libs")
FileUtils.cp File.join(@framework_dir, "phonegap.#{ version }.jar"), File.join(@path, "libs")
FileUtils.cp File.join(@framework_dir, "phonegap-#{ version }.jar"), File.join(@path, "libs")
# copies in the strings.xml
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")
# copies in plugins.xml
FileUtils.mkdir_p File.join(app_res_dir, "xml")
FileUtils.cp File.join(framework_res_dir, "xml","plugins.xml"), File.join(app_res_dir, "xml", "plugins.xml")
# drops in the layout files: main.xml and preview.xml
FileUtils.mkdir_p File.join(app_res_dir, "layout")
%w(main.xml).each do |f|
@@ -125,7 +128,7 @@ class Classic
phonegapjs << IO.read(File.join(js_dir, script))
phonegapjs << "\n\n"
end
File.open(File.join(@path, "assets", "www", @app_js_dir, "phonegap.#{ version }.js"), 'w') {|f| f.write(phonegapjs) }
File.open(File.join(@path, "assets", "www", @app_js_dir, "phonegap-#{ version }.js"), 'w') {|f| f.write(phonegapjs) }
end
# puts app name in strings

View File

@@ -35,7 +35,7 @@ class Update
puts "Copying over libraries and assets..."
version = IO.read(File.join(@framework_dir, '../VERSION'))
FileUtils.cp File.join(@framework_dir, "phonegap.#{ version }.jar"), File.join(@path, "libs")
FileUtils.cp File.join(@framework_dir, "phonegap-#{ version }.jar"), File.join(@path, "libs")
# concat JS and put into www folder. this can be overridden in the config.xml via @app_js_dir
js_dir = File.join(@framework_dir, "assets", "js")
@@ -45,7 +45,7 @@ class Update
phonegapjs << IO.read(File.join(js_dir, script))
phonegapjs << "\n\n"
end
File.open(File.join(@path, "assets", "www", "phonegap.#{ version }.js"), 'w') {|f| f.write(phonegapjs) }
File.open(File.join(@path, "assets", "www", "phonegap-#{ version }.js"), 'w') {|f| f.write(phonegapjs) }
end
#
end