diff --git a/example/index.html b/example/index.html
index bdfee7c3..ecf05ee7 100644
--- a/example/index.html
+++ b/example/index.html
@@ -104,6 +104,7 @@
var obj = new ContactFindOptions();
obj.filter="";
obj.multiple=true;
+ obj.limit=5;
navigator.service.contacts.find(["displayName", "phoneNumbers", "emails"], count_contacts, fail, obj);
}
diff --git a/framework/assets/js/accelerometer.js b/framework/assets/js/accelerometer.js
index 3923a56a..f87cd082 100755
--- a/framework/assets/js/accelerometer.js
+++ b/framework/assets/js/accelerometer.js
@@ -102,7 +102,7 @@ Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallb
Accelerometer.prototype.clearWatch = function(id) {
// Stop javascript timer & remove from timer list
- if (id && navigator.accelerometer.timers[id]) {
+ if (id && navigator.accelerometer.timers[id] != undefined) {
clearInterval(navigator.accelerometer.timers[id]);
delete navigator.accelerometer.timers[id];
}
diff --git a/framework/assets/js/contact.js b/framework/assets/js/contact.js
index 1d5eb4c0..2d735027 100644
--- a/framework/assets/js/contact.js
+++ b/framework/assets/js/contact.js
@@ -27,6 +27,27 @@ var Contact = function(id, displayName, name, nickname, phoneNumbers, emails, ad
this.connected = connected || null;
};
+
+Contact.prototype.remove = function(successCB, errorCB) {
+ if (this.id == null) {
+ var errorObj = new ContactError();
+ errorObj.code = ContactError.NOT_FOUND_ERROR;
+ errorCB(errorObj);
+ }
+
+ PhoneGap.execAsync(successCB, errorCB, "Contacts", "remove", [this.id]);
+};
+
+Contact.prototype.clone = function() {
+ var clonedContact = PhoneGap.clone(this);
+ clonedContact.id = null;
+ return clonedContact;
+};
+
+Contact.prototype.save = function(win, fail) {
+};
+
+
var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
this.formatted = formatted || null;
this.familyName = familyName || null;
@@ -72,30 +93,26 @@ var Contacts = function() {
this.records = new Array();
}
-// Contacts.prototype.find = function(obj, win, fail) {
Contacts.prototype.find = function(fields, win, fail, options) {
- this.win = win;
- this.fail = fail;
-
- PhoneGap.execAsync(null, null, "Contacts", "search", [fields, options]);
+ PhoneGap.execAsync(win, fail, "Contacts", "search", [fields, options]);
+};
+
+//This function does not create a new contact in the db.
+//Must call contact.save() for it to be persisted in the db.
+Contacts.prototype.create = function(properties) {
+ var contact = new Contact();
+ for (i in properties) {
+ if (contact[i]!='undefined') {
+ contact[i]=properties[i];
+ }
+ }
+ return contact;
};
Contacts.prototype.droidDone = function(contacts) {
this.win(eval('(' + contacts + ')'));
};
-Contacts.prototype.remove = function(contact) {
-
-};
-
-Contacts.prototype.save = function(contact) {
-
-};
-
-Contacts.prototype.create = function(contact) {
-
-};
-
Contacts.prototype.m_foundContacts = function(win, contacts) {
this.inProgress = false;
win(contacts);
@@ -112,14 +129,14 @@ var ContactError = function() {
this.code=null;
};
-ContactError.INVALID_ARGUMENT_ERROR = 0;
-ContactError.IO_ERROR = 1;
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
ContactError.NOT_FOUND_ERROR = 2;
-ContactError.NOT_SUPPORTED_ERROR = 3;
+ContactError.TIMEOUT_ERROR = 3;
ContactError.PENDING_OPERATION_ERROR = 4;
-ContactError.PERMISSION_DENIED_ERROR = 5;
-ContactError.TIMEOUT_ERROR = 6;
-ContactError.UNKNOWN_ERROR = 7;
+ContactError.IO_ERROR = 5;
+ContactError.NOT_SUPPORTED_ERROR = 6;
+ContactError.PERMISSION_DENIED_ERROR = 20;
PhoneGap.addConstructor(function() {
if(typeof navigator.service == "undefined") navigator.service = new Object();
diff --git a/framework/assets/js/phonegap.js.base b/framework/assets/js/phonegap.js.base
index 0c31d018..ab71d3d7 100755
--- a/framework/assets/js/phonegap.js.base
+++ b/framework/assets/js/phonegap.js.base
@@ -324,6 +324,42 @@ PhoneGap.stringify = function(args) {
}
};
+/**
+ * Does a deep clone of the object.
+ *
+ * @param obj
+ * @return
+ */
+PhoneGap.clone = function(obj) {
+ if(!obj) {
+ return obj;
+ }
+
+ if(obj instanceof Array){
+ var retVal = new Array();
+ for(var i = 0; i < obj.length; ++i){
+ retVal.push(PhoneGap.clone(obj[i]));
+ }
+ return retVal;
+ }
+
+ if (obj instanceof Function) {
+ return obj;
+ }
+
+ if(!(obj instanceof Object)){
+ return obj;
+ }
+
+ retVal = new Object();
+ for(i in obj){
+ if(!(i in retVal) || retVal[i] != obj[i]) {
+ retVal[i] = PhoneGap.clone(obj[i]);
+ }
+ }
+ return retVal;
+};
+
PhoneGap.callbackId = 0;
PhoneGap.callbacks = {};
diff --git a/framework/assets/www/phonegap.js b/framework/assets/www/phonegap.js
index 0964a8eb..8aa92570 100644
--- a/framework/assets/www/phonegap.js
+++ b/framework/assets/www/phonegap.js
@@ -324,6 +324,42 @@ PhoneGap.stringify = function(args) {
}
};
+/**
+ * Does a deep clone of the object.
+ *
+ * @param obj
+ * @return
+ */
+PhoneGap.clone = function(obj) {
+ if(!obj) {
+ return obj;
+ }
+
+ if(obj instanceof Array){
+ var retVal = new Array();
+ for(var i = 0; i < obj.length; ++i){
+ retVal.push(PhoneGap.clone(obj[i]));
+ }
+ return retVal;
+ }
+
+ if (obj instanceof Function) {
+ return obj;
+ }
+
+ if(!(obj instanceof Object)){
+ return obj;
+ }
+
+ retVal = new Object();
+ for(i in obj){
+ if(!(i in retVal) || retVal[i] != obj[i]) {
+ retVal[i] = PhoneGap.clone(obj[i]);
+ }
+ }
+ return retVal;
+};
+
PhoneGap.callbackId = 0;
PhoneGap.callbacks = {};
@@ -687,7 +723,7 @@ Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallb
Accelerometer.prototype.clearWatch = function(id) {
// Stop javascript timer & remove from timer list
- if (id && navigator.accelerometer.timers[id]) {
+ if (id && navigator.accelerometer.timers[id] != undefined) {
clearInterval(navigator.accelerometer.timers[id]);
delete navigator.accelerometer.timers[id];
}
@@ -940,6 +976,27 @@ var Contact = function(id, displayName, name, nickname, phoneNumbers, emails, ad
this.connected = connected || null;
};
+
+Contact.prototype.remove = function(successCB, errorCB) {
+ if (this.id == null) {
+ var errorObj = new ContactError();
+ errorObj.code = ContactError.NOT_FOUND_ERROR;
+ errorCB(errorObj);
+ }
+
+ PhoneGap.execAsync(successCB, errorCB, "Contacts", "remove", [this.id]);
+};
+
+Contact.prototype.clone = function() {
+ var clonedContact = PhoneGap.clone(this);
+ clonedContact.id = null;
+ return clonedContact;
+};
+
+Contact.prototype.save = function(win, fail) {
+};
+
+
var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
this.formatted = formatted || null;
this.familyName = familyName || null;
@@ -985,30 +1042,26 @@ var Contacts = function() {
this.records = new Array();
}
-// Contacts.prototype.find = function(obj, win, fail) {
Contacts.prototype.find = function(fields, win, fail, options) {
- this.win = win;
- this.fail = fail;
-
- PhoneGap.execAsync(null, null, "Contacts", "search", [fields, options]);
+ PhoneGap.execAsync(win, fail, "Contacts", "search", [fields, options]);
+};
+
+//This function does not create a new contact in the db.
+//Must call contact.save() for it to be persisted in the db.
+Contacts.prototype.create = function(properties) {
+ var contact = new Contact();
+ for (i in properties) {
+ if (contact[i]!='undefined') {
+ contact[i]=properties[i];
+ }
+ }
+ return contact;
};
Contacts.prototype.droidDone = function(contacts) {
this.win(eval('(' + contacts + ')'));
};
-Contacts.prototype.remove = function(contact) {
-
-};
-
-Contacts.prototype.save = function(contact) {
-
-};
-
-Contacts.prototype.create = function(contact) {
-
-};
-
Contacts.prototype.m_foundContacts = function(win, contacts) {
this.inProgress = false;
win(contacts);
@@ -1025,14 +1078,14 @@ var ContactError = function() {
this.code=null;
};
-ContactError.INVALID_ARGUMENT_ERROR = 0;
-ContactError.IO_ERROR = 1;
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
ContactError.NOT_FOUND_ERROR = 2;
-ContactError.NOT_SUPPORTED_ERROR = 3;
+ContactError.TIMEOUT_ERROR = 3;
ContactError.PENDING_OPERATION_ERROR = 4;
-ContactError.PERMISSION_DENIED_ERROR = 5;
-ContactError.TIMEOUT_ERROR = 6;
-ContactError.UNKNOWN_ERROR = 7;
+ContactError.IO_ERROR = 5;
+ContactError.NOT_SUPPORTED_ERROR = 6;
+ContactError.PERMISSION_DENIED_ERROR = 20;
PhoneGap.addConstructor(function() {
if(typeof navigator.service == "undefined") navigator.service = new Object();
diff --git a/framework/src/com/phonegap/ContactAccessor.java b/framework/src/com/phonegap/ContactAccessor.java
index ac03c414..e276118c 100644
--- a/framework/src/com/phonegap/ContactAccessor.java
+++ b/framework/src/com/phonegap/ContactAccessor.java
@@ -19,11 +19,14 @@
package com.phonegap;
import java.lang.reflect.Constructor;
+import java.util.HashMap;
import android.app.Activity;
+import android.util.Log;
import android.webkit.WebView;
import org.json.JSONArray;
+import org.json.JSONException;
import org.json.JSONObject;
/**
@@ -82,9 +85,78 @@ public abstract class ContactAccessor {
return sInstance;
}
+
+ protected boolean isRequired(String key, HashMap map) {
+ Boolean retVal = map.get(key);
+ return (retVal == null) ? false : retVal.booleanValue();
+ }
+
+ protected HashMap buildPopulationSet(JSONArray filter) {
+ HashMap map = new HashMap();
+
+ String key;
+ try {
+ for (int i=0; i contactIds = buildSetOfContactIds(filter, searchTerm);
-
+ HashMap populate = buildPopulationSet(filter);
+
Iterator it = contactIds.iterator();
JSONArray contacts = new JSONArray();
@@ -124,20 +125,27 @@ public class ContactAccessorSdk3_4 extends ContactAccessor {
null);
cur.moveToFirst();
- // name
- contact.put("displayName", cur.getString(cur.getColumnIndex(People.DISPLAY_NAME)));
- // phone number
- contact.put("phoneNumbers", phoneQuery(cr, contactId));
- // email
- contact.put("emails", emailQuery(cr, contactId));
- // addresses
- contact.put("addresses", addressQuery(cr, contactId));
- // organizations
- contact.put("organizations", organizationQuery(cr, contactId));
- // ims
- contact.put("ims", imQuery(cr, contactId));
- // note
- contact.put("note", cur.getString(cur.getColumnIndex(People.NOTES)));
+ if (isRequired("displayName",populate)) {
+ contact.put("displayName", cur.getString(cur.getColumnIndex(People.DISPLAY_NAME)));
+ }
+ if (isRequired("phoneNumbers",populate)) {
+ contact.put("phoneNumbers", phoneQuery(cr, contactId));
+ }
+ if (isRequired("emails",populate)) {
+ contact.put("emails", emailQuery(cr, contactId));
+ }
+ if (isRequired("addresses",populate)) {
+ contact.put("addresses", addressQuery(cr, contactId));
+ }
+ if (isRequired("organizations",populate)) {
+ contact.put("organizations", organizationQuery(cr, contactId));
+ }
+ if (isRequired("ims",populate)) {
+ contact.put("ims", imQuery(cr, contactId));
+ }
+ if (isRequired("note",populate)) {
+ contact.put("note", cur.getString(cur.getColumnIndex(People.NOTES)));
+ }
// nickname
// urls
// relationship
@@ -151,7 +159,7 @@ public class ContactAccessorSdk3_4 extends ContactAccessor {
}
contacts.put(contact);
}
- mView.loadUrl("javascript:navigator.service.contacts.droidDone('" + contacts.toString() + "');");
+ return contacts;
}
private Set buildSetOfContactIds(JSONArray filter, String searchTerm) {
@@ -359,4 +367,19 @@ public class ContactAccessorSdk3_4 extends ContactAccessor {
}
return emails;
}
+
+ @Override
+ public void save(JSONObject contact) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean remove(String id) {
+ int result = mApp.getContentResolver().delete(People.CONTENT_URI,
+ "people._id = ?",
+ new String[] {id});
+
+ return (result > 0) ? true : false;
+ }
}
\ No newline at end of file
diff --git a/framework/src/com/phonegap/ContactAccessorSdk5.java b/framework/src/com/phonegap/ContactAccessorSdk5.java
index bcad148f..b4ab52a6 100644
--- a/framework/src/com/phonegap/ContactAccessorSdk5.java
+++ b/framework/src/com/phonegap/ContactAccessorSdk5.java
@@ -107,14 +107,13 @@ public class ContactAccessorSdk5 extends ContactAccessor {
//dbMap.put("connected", null);
}
- public ContactAccessorSdk5(WebView view, Activity app)
- {
+ public ContactAccessorSdk5(WebView view, Activity app) {
mApp = app;
mView = view;
}
@Override
- public void search(JSONArray filter, JSONObject options) {
+ public JSONArray search(JSONArray filter, JSONObject options) {
String searchTerm = "";
int limit = Integer.MAX_VALUE;
boolean multiple = true;
@@ -133,49 +132,90 @@ public class ContactAccessorSdk5 extends ContactAccessor {
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
}
+
// Get a cursor by creating the query.
ContentResolver cr = mApp.getContentResolver();
Set contactIds = buildSetOfContactIds(filter, searchTerm);
-
+ HashMap populate = buildPopulationSet(filter);
+
Iterator it = contactIds.iterator();
JSONArray contacts = new JSONArray();
JSONObject contact;
String contactId;
int pos = 0;
+ String[] events = null;
while (it.hasNext() && (pos < limit)) {
contact = new JSONObject();
contactId = it.next();
try {
contact.put("id", contactId);
- contact.put("displayName", displayNameQuery(cr, contactId));
- contact.put("name", nameQuery(cr, contactId));
- contact.put("phoneNumbers", phoneQuery(cr, contactId));
- contact.put("emails", emailQuery(cr, contactId));
- contact.put("addresses", addressQuery(cr, contactId));
- contact.put("organizations", organizationQuery(cr, contactId));
- contact.put("ims",imQuery(cr, contactId));
- contact.put("note",noteQuery(cr, contactId));
- contact.put("nickname",nicknameQuery(cr, contactId));
- contact.put("urls",websiteQuery(cr, contactId));
- contact.put("relationships",relationshipQuery(cr, contactId));
- contact.put("birthday",birthdayQuery(cr, contactId));
- contact.put("anniversary",anniversaryQuery(cr, contactId));
+ if (isRequired("displayName",populate)) {
+ contact.put("displayName", displayNameQuery(cr, contactId));
+ }
+ if (isRequired("name",populate)) {
+ contact.put("name", nameQuery(cr, contactId));
+ }
+ if (isRequired("phoneNumbers",populate)) {
+ contact.put("phoneNumbers", phoneQuery(cr, contactId));
+ }
+ if (isRequired("emails",populate)) {
+ contact.put("emails", emailQuery(cr, contactId));
+ }
+ if (isRequired("addresses",populate)) {
+ contact.put("addresses", addressQuery(cr, contactId));
+ }
+ if (isRequired("organizations",populate)) {
+ contact.put("organizations", organizationQuery(cr, contactId));
+ }
+ if (isRequired("ims",populate)) {
+ contact.put("ims",imQuery(cr, contactId));
+ }
+ if (isRequired("note",populate)) {
+ contact.put("note",noteQuery(cr, contactId));
+ }
+ if (isRequired("nickname",populate)) {
+ contact.put("nickname",nicknameQuery(cr, contactId));
+ }
+ if (isRequired("urls",populate)) {
+ contact.put("urls",websiteQuery(cr, contactId));
+ }
+ if (isRequired("relationships",populate)) {
+ contact.put("relationships",relationshipQuery(cr, contactId));
+ }
+ if (isRequired("birthday",populate) || isRequired("anniversary",populate)) {
+ events = eventQuery(cr, contactId);
+ contact.put("birthday",events[0]);
+ contact.put("anniversary",events[1]);
+ }
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
}
+ Log.d(LOG_TAG, "putting in contact ID = " + contactId);
contacts.put(contact);
pos++;
- }
- mView.loadUrl("javascript:navigator.service.contacts.droidDone('" + contacts.toString() + "');");
+ }
+ return contacts;
}
-
+
private Set buildSetOfContactIds(JSONArray filter, String searchTerm) {
Set contactIds = new HashSet();
+ /*
+ * Special case for when the user wants all the contacts
+ */
+ if ("%".equals(searchTerm)) {
+ doQuery(searchTerm, contactIds,
+ ContactsContract.Contacts.CONTENT_URI,
+ ContactsContract.Contacts._ID,
+ ContactsContract.Contacts.DISPLAY_NAME + " LIKE ?",
+ new String[] {searchTerm});
+ return contactIds;
+ }
+
String key;
try {
for (int i=0; i 0) ? true : false;
}
}
\ No newline at end of file
diff --git a/framework/src/com/phonegap/ContactManager.java b/framework/src/com/phonegap/ContactManager.java
index 9cf6a891..3d3bb7e4 100755
--- a/framework/src/com/phonegap/ContactManager.java
+++ b/framework/src/com/phonegap/ContactManager.java
@@ -2,6 +2,7 @@ package com.phonegap;
import org.json.JSONArray;
import org.json.JSONException;
+import org.json.JSONObject;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
@@ -60,16 +61,21 @@ public class ContactManager implements Plugin {
try {
if (action.equals("search")) {
- contactAccessor.search(args.getJSONArray(0), args.getJSONObject(1));
- }
- else if (action.equals("create")) {
- // TODO Coming soon!
+ JSONArray res = contactAccessor.search(args.getJSONArray(0), args.getJSONObject(1));
+ return new PluginResult(status, res);
}
else if (action.equals("save")) {
// TODO Coming soon!
}
else if (action.equals("remove")) {
- // TODO Coming soon!
+ 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);
} catch (JSONException e) {
diff --git a/framework/src/com/phonegap/api/PluginResult.java b/framework/src/com/phonegap/api/PluginResult.java
index 777f2605..7523bfe7 100755
--- a/framework/src/com/phonegap/api/PluginResult.java
+++ b/framework/src/com/phonegap/api/PluginResult.java
@@ -1,5 +1,6 @@
package com.phonegap.api;
+import org.json.JSONArray;
import org.json.JSONObject;
public class PluginResult {
@@ -16,6 +17,11 @@ public class PluginResult {
this.message = "'" + message + "'";
}
+ public PluginResult(Status status, JSONArray message) {
+ this.status = status.ordinal();
+ this.message = message.toString();
+ }
+
public PluginResult(Status status, JSONObject message) {
this.status = status.ordinal();
this.message = message.toString();