diff --git a/framework/src/org/apache/cordova/AudioPlayer.java b/framework/src/org/apache/cordova/AudioPlayer.java index 72efcdae..856cc7b7 100755 --- a/framework/src/org/apache/cordova/AudioPlayer.java +++ b/framework/src/org/apache/cordova/AudioPlayer.java @@ -37,8 +37,8 @@ import java.io.IOException; * Only one file can be played or recorded per class instance. * * Local audio files must reside in one of two places: - * android_asset: file name must start with /android_asset/sound.mp3 - * sdcard: file name is just sound.mp3 + * android_asset: file name must start with /android_asset/sound.mp3 + * sdcard: file name is just sound.mp3 */ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener { @@ -56,43 +56,47 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On private static int MEDIA_DURATION = 2; private static int MEDIA_POSITION = 3; private static int MEDIA_ERROR = 9; - + // Media error codes - private static int MEDIA_ERR_NONE_ACTIVE = 0; - private static int MEDIA_ERR_ABORTED = 1; -// private static int MEDIA_ERR_NETWORK = 2; -// private static int MEDIA_ERR_DECODE = 3; -// private static int MEDIA_ERR_NONE_SUPPORTED = 4; + private static int MEDIA_ERR_NONE_ACTIVE = 0; + private static int MEDIA_ERR_ABORTED = 1; + private static int MEDIA_ERR_NETWORK = 2; + private static int MEDIA_ERR_DECODE = 3; + private static int MEDIA_ERR_NONE_SUPPORTED = 4; + + private AudioHandler handler; // The AudioHandler object + private String id; // The id of this player (used to identify Media object in JavaScript) + private int state = MEDIA_NONE; // State of recording or playback + private String audioFile = null; // File name to play or record to + private float duration = -1; // Duration of audio - private AudioHandler handler; // The AudioHandler object - private String id; // The id of this player (used to identify Media object in JavaScript) - private int state = MEDIA_NONE; // State of recording or playback - private String audioFile = null; // File name to play or record to - private float duration = -1; // Duration of audio - - private MediaRecorder recorder = null; // Audio recording object - private String tempFile = null; // Temporary recording file name - - private MediaPlayer mPlayer = null; // Audio player object + private MediaRecorder recorder = null; // Audio recording object + private String tempFile = null; // Temporary recording file name + + private MediaPlayer mPlayer = null; // Audio player object private boolean prepareOnly = false; /** * Constructor. * - * @param handler The audio handler object - * @param id The id of this audio player + * @param handler The audio handler object + * @param id The id of this audio player */ public AudioPlayer(AudioHandler handler, String id) { this.handler = handler; this.id = id; - this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3"; - } + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3"; + } else { + this.tempFile = "/data/data/" + handler.ctx.getPackageName() + "/cache/tmprecording.mp3"; + } + } /** * Destroy player and stop audio playing or recording. */ public void destroy() { - + // Stop any play or record if (this.mPlayer != null) { if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) { @@ -112,14 +116,14 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On /** * Start recording the specified file. * - * @param file The name of the file + * @param file The name of the file */ public void startRecording(String file) { if (this.mPlayer != null) { Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode."); - this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});"); + this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});"); } - + // Make sure we're not already recording else if (this.recorder == null) { this.audioFile = file; @@ -138,26 +142,31 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On } catch (IOException e) { e.printStackTrace(); } - this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});"); + this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});"); } else { Log.d(LOG_TAG, "AudioPlayer Error: Already recording."); - this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});"); + this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});"); } } - + /** * Save temporary recorded file to specified name * * @param file */ - public void moveFile(String file) { - + public void moveFile(String file) { /* this is a hack to save the file as the specified name */ File f = new File(this.tempFile); - f.renameTo(new File("/sdcard/" + file)); + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + f.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + file)); + } else { + f.renameTo(new File("/data/data/" + handler.ctx.getPackageName() + "/cache/" + file)); + } + } - + /** * Stop recording and save to the file specified when recording started. */ @@ -178,7 +187,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On /** * Start or resume playing audio file. * - * @param file The name of the audio file. + * @param file The name of the audio file. */ public void startPlaying(String file) { if (this.recorder != null) { @@ -297,7 +306,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On /** * Callback to be invoked when playback of a media source has completed. * - * @param mPlayer The MediaPlayer that reached the end of the file + * @param mPlayer The MediaPlayer that reached the end of the file */ public void onCompletion(MediaPlayer mPlayer) { this.setState(MEDIA_STOPPED); @@ -306,7 +315,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On /** * Get current position of playback. * - * @return position in msec or -1 if not playing + * @return position in msec or -1 if not playing */ public long getCurrentPosition() { if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) { @@ -323,8 +332,8 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On * Determine if playback file is streaming or local. * It is streaming if file name starts with "http://" * - * @param file The file name - * @return T=streaming, F=local + * @param file The file name + * @return T=streaming, F=local */ public boolean isStreaming(String file) { if (file.contains("http://") || file.contains("https://")) { @@ -338,10 +347,10 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On /** * Get the duration of the audio file. * - * @param file The name of the audio file. - * @return The duration in msec. - * -1=can't be determined - * -2=not allowed + * @param file The name of the audio file. + * @return The duration in msec. + * -1=can't be determined + * -2=not allowed */ public float getDuration(String file) { @@ -369,7 +378,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On /** * Callback to be invoked when the media source is ready for playback. * - * @param mPlayer The MediaPlayer that is ready for playback + * @param mPlayer The MediaPlayer that is ready for playback */ public void onPrepared(MediaPlayer mPlayer) { // Listen for playback completion @@ -407,9 +416,9 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On * Callback to be invoked when there has been an error during an asynchronous operation * (other errors will throw exceptions at method call time). * - * @param mPlayer the MediaPlayer the error pertains to - * @param arg1 the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED) - * @param arg2 an extra code, specific to the error. + * @param mPlayer the MediaPlayer the error pertains to + * @param arg1 the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED) + * @param arg2 an extra code, specific to the error. */ public boolean onError(MediaPlayer mPlayer, int arg1, int arg2) { Log.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")"); diff --git a/framework/src/org/apache/cordova/ContactAccessor.java b/framework/src/org/apache/cordova/ContactAccessor.java index 99c375af..f4ceed1d 100644 --- a/framework/src/org/apache/cordova/ContactAccessor.java +++ b/framework/src/org/apache/cordova/ContactAccessor.java @@ -18,8 +18,7 @@ package org.apache.cordova; import java.util.HashMap; -//import android.app.Activity; -//import android.content.Context; +import android.content.Context; import android.util.Log; import android.webkit.WebView; @@ -48,19 +47,19 @@ public abstract class ContactAccessor { * @param map created by running buildPopulationSet. * @return true if the key data is required */ - protected boolean isRequired(String key, HashMap<String, Boolean> map) { + protected boolean isRequired(String key, HashMap<String,Boolean> map) { Boolean retVal = map.get(key); return (retVal == null) ? false : retVal.booleanValue(); } - + /** * Create a hash map of what data needs to be populated in the Contact object * @param fields the list of fields to populate * @return the hash map of required data */ - protected HashMap<String, Boolean> buildPopulationSet(JSONArray fields) { - HashMap<String, Boolean> map = new HashMap<String, Boolean>(); - + protected HashMap<String,Boolean> buildPopulationSet(JSONArray fields) { + HashMap<String,Boolean> map = new HashMap<String,Boolean>(); + String key; try { if (fields.length() == 1 && fields.getString(0).equals("*")) { @@ -77,9 +76,9 @@ public abstract class ContactAccessor { map.put("urls", true); map.put("photos", true); map.put("categories", true); - } + } else { - for (int i = 0; i < fields.length(); i++) { + for (int i=0; i<fields.length(); i++) { key = fields.getString(i); if (key.startsWith("displayName")) { map.put("displayName", true); @@ -123,12 +122,13 @@ public abstract class ContactAccessor { } } } - } catch (JSONException e) { + } + catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return map; } - + /** * Convenience method to get a string from a JSON object. Saves a * lot of try/catch writing. @@ -148,9 +148,10 @@ public abstract class ContactAccessor { value = null; } } - } catch (JSONException e) { + } + catch (JSONException e) { Log.d(LOG_TAG, "Could not get = " + e.getMessage()); - } + } return value; } @@ -176,25 +177,21 @@ public abstract class ContactAccessor { */ public abstract boolean remove(String id); - /** + /** * A class that represents the where clause to be used in the database query */ class WhereOptions { private String where; private String[] whereArgs; - public void setWhere(String where) { this.where = where; } - public String getWhere() { return where; } - public void setWhereArgs(String[] whereArgs) { this.whereArgs = whereArgs; } - public String[] getWhereArgs() { return whereArgs; } diff --git a/framework/src/org/apache/cordova/ContactAccessorSdk5.java b/framework/src/org/apache/cordova/ContactAccessorSdk5.java index 0f41814b..ec7b39fd 100644 --- a/framework/src/org/apache/cordova/ContactAccessorSdk5.java +++ b/framework/src/org/apache/cordova/ContactAccessorSdk5.java @@ -25,7 +25,10 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -85,39 +88,39 @@ public class ContactAccessorSdk5 extends ContactAccessor { */ private static final Map<String, String> dbMap = new HashMap<String, String>(); static { - 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); - dbMap.put("name.familyName", ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME); - dbMap.put("name.givenName", ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME); - dbMap.put("name.middleName", ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME); - dbMap.put("name.honorificPrefix", ContactsContract.CommonDataKinds.StructuredName.PREFIX); - dbMap.put("name.honorificSuffix", ContactsContract.CommonDataKinds.StructuredName.SUFFIX); - dbMap.put("nickname", ContactsContract.CommonDataKinds.Nickname.NAME); - dbMap.put("phoneNumbers", ContactsContract.CommonDataKinds.Phone.NUMBER); - dbMap.put("phoneNumbers.value", ContactsContract.CommonDataKinds.Phone.NUMBER); - dbMap.put("emails", ContactsContract.CommonDataKinds.Email.DATA); - dbMap.put("emails.value", ContactsContract.CommonDataKinds.Email.DATA); - dbMap.put("addresses", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS); - dbMap.put("addresses.formatted", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS); - dbMap.put("addresses.streetAddress", ContactsContract.CommonDataKinds.StructuredPostal.STREET); - dbMap.put("addresses.locality", ContactsContract.CommonDataKinds.StructuredPostal.CITY); - dbMap.put("addresses.region", ContactsContract.CommonDataKinds.StructuredPostal.REGION); - dbMap.put("addresses.postalCode", ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE); - dbMap.put("addresses.country", ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY); - dbMap.put("ims", ContactsContract.CommonDataKinds.Im.DATA); - dbMap.put("ims.value", ContactsContract.CommonDataKinds.Im.DATA); - dbMap.put("organizations", ContactsContract.CommonDataKinds.Organization.COMPANY); - 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("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("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); + dbMap.put("name.familyName", ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME); + dbMap.put("name.givenName", ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME); + dbMap.put("name.middleName", ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME); + dbMap.put("name.honorificPrefix", ContactsContract.CommonDataKinds.StructuredName.PREFIX); + dbMap.put("name.honorificSuffix", ContactsContract.CommonDataKinds.StructuredName.SUFFIX); + dbMap.put("nickname", ContactsContract.CommonDataKinds.Nickname.NAME); + dbMap.put("phoneNumbers", ContactsContract.CommonDataKinds.Phone.NUMBER); + dbMap.put("phoneNumbers.value", ContactsContract.CommonDataKinds.Phone.NUMBER); + dbMap.put("emails", ContactsContract.CommonDataKinds.Email.DATA); + dbMap.put("emails.value", ContactsContract.CommonDataKinds.Email.DATA); + dbMap.put("addresses", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS); + dbMap.put("addresses.formatted", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS); + dbMap.put("addresses.streetAddress", ContactsContract.CommonDataKinds.StructuredPostal.STREET); + dbMap.put("addresses.locality", ContactsContract.CommonDataKinds.StructuredPostal.CITY); + dbMap.put("addresses.region", ContactsContract.CommonDataKinds.StructuredPostal.REGION); + dbMap.put("addresses.postalCode", ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE); + dbMap.put("addresses.country", ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY); + dbMap.put("ims", ContactsContract.CommonDataKinds.Im.DATA); + dbMap.put("ims.value", ContactsContract.CommonDataKinds.Im.DATA); + dbMap.put("organizations", ContactsContract.CommonDataKinds.Organization.COMPANY); + 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("birthday", ContactsContract.CommonDataKinds.Event.START_DATE); + 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); } /** @@ -536,67 +539,71 @@ public class ContactAccessorSdk5 extends ContactAccessor { where.add("(" + dbMap.get(key) + " LIKE ? )"); whereArgs.add(searchTerm); } - else if (key.startsWith("name")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); - } - else if (key.startsWith("nickname")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE); - } - else if (key.startsWith("phoneNumbers")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); - } - else if (key.startsWith("emails")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE); - } - else if (key.startsWith("addresses")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE); - } - else if (key.startsWith("ims")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE); - } - else if (key.startsWith("organizations")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE); - } - // else if (key.startsWith("birthday")) { -// where.add("(" + dbMap.get(key) + " LIKE ? AND " -// + ContactsContract.Data.MIMETYPE + " = ? )"); -// } - else if (key.startsWith("note")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE); - } - else if (key.startsWith("urls")) { - where.add("(" + dbMap.get(key) + " LIKE ? AND " - + ContactsContract.Data.MIMETYPE + " = ? )"); - whereArgs.add(searchTerm); - whereArgs.add(ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE); - } + else if (key.startsWith("name")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); + } + else if (key.startsWith("nickname")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE); + } + else if (key.startsWith("phoneNumbers")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); + } + else if (key.startsWith("emails")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE); + } + else if (key.startsWith("addresses")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE); + } + else if (key.startsWith("ims")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE); + } + else if (key.startsWith("organizations")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE); + } + else if (key.startsWith("birthday")) { + try { + SimpleDateFormat format = new SimpleDateFormat("EEEE, MMMM dd, yyyy"); + Date searchDate = format.parse(searchTerm.substring(1, searchTerm.length()-1)); + // Have to subtract one from the month as JavaScript's January is 01 + // while Java's January is 00. + searchDate.setMonth(searchDate.getMonth()-1); + SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd"); + + where.add("(" + dbMap.get(key) + " = ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(newFormat.format(searchDate)); + whereArgs.add(ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE); } - } catch (JSONException e) { - Log.e(LOG_TAG, e.getMessage(), e); + catch (ParseException e) { + Log.d(LOG_TAG, "Bad romance format"); + } + } + else if (key.startsWith("note")) { + where.add("(" + dbMap.get(key) + " LIKE ? AND " + + ContactsContract.Data.MIMETYPE + " = ? )"); + whereArgs.add(searchTerm); + whereArgs.add(ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE); } // Creating the where string @@ -1128,18 +1135,47 @@ public class ContactAccessorSdk5 extends ContactAccessor { Log.d(LOG_TAG, "Could not get emails"); } - // Modify note - String note = getJsonString(contact, "note"); - ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) - .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + - ContactsContract.Data.MIMETYPE + "=?", - new String[] { id, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE }) - .withValue(ContactsContract.CommonDataKinds.Note.NOTE, note) - .build()); + // Modify note + String note = getJsonString(contact, "note"); + ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) + .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + + ContactsContract.Data.MIMETYPE + "=?", + new String[]{id,ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE}) + .withValue(ContactsContract.CommonDataKinds.Note.NOTE, note) + .build()); - // Modify nickname - String nickname = getJsonString(contact, "nickname"); - if (nickname != null) { + // Modify nickname + String nickname = getJsonString(contact, "nickname"); + if (nickname != null) { + ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) + .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + + ContactsContract.Data.MIMETYPE + "=?", + new String[]{id,ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE}) + .withValue(ContactsContract.CommonDataKinds.Nickname.NAME, nickname) + .build()); + } + + // Modify urls + JSONArray websites = null; + try { + websites = contact.getJSONArray("urls"); + if (websites != null) { + for (int i=0; i<websites.length(); i++) { + JSONObject website = (JSONObject)websites.get(i); + String websiteId = getJsonString(website, "id"); + // This is a new website so do a DB insert + if (websiteId==null) { + ContentValues contentValues = new ContentValues(); + contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); + contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE); + contentValues.put(ContactsContract.CommonDataKinds.Website.DATA, getJsonString(website, "value")); + contentValues.put(ContactsContract.CommonDataKinds.Website.TYPE, getContactType(getJsonString(website, "type"))); + + ops.add(ContentProviderOperation.newInsert( + ContactsContract.Data.CONTENT_URI).withValues(contentValues).build()); + } + // This is an existing website so do a DB update + else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", diff --git a/framework/src/org/apache/cordova/api/PluginResult.java b/framework/src/org/apache/cordova/api/PluginResult.java index 8f5f7fdb..4d05ddd3 100755 --- a/framework/src/org/apache/cordova/api/PluginResult.java +++ b/framework/src/org/apache/cordova/api/PluginResult.java @@ -27,12 +27,12 @@ public class PluginResult { private final int status; private final String message; private boolean keepCallback = false; - + public PluginResult(Status status) { this.status = status.ordinal(); this.message = "'" + PluginResult.StatusMessages[this.status] + "'"; } - + public PluginResult(Status status, String message) { this.status = status.ordinal(); this.message = JSONObject.quote(message); @@ -50,23 +50,23 @@ public class PluginResult { public PluginResult(Status status, int i) { this.status = status.ordinal(); - this.message = "" + i; + this.message = ""+i; } public PluginResult(Status status, float f) { this.status = status.ordinal(); - this.message = "" + f; + this.message = ""+f; } public PluginResult(Status status, boolean b) { this.status = status.ordinal(); - this.message = "" + b; + this.message = ""+b; } - + public void setKeepCallback(boolean b) { this.keepCallback = b; } - + public int getStatus() { return status; } @@ -74,36 +74,36 @@ public class PluginResult { public String getMessage() { return message; } - + public boolean getKeepCallback() { return this.keepCallback; } - + public String getJSONString() { - return "{status:" + this.status + ",message:" + this.message + ",keepCallback:" + this.keepCallback + "}"; + return "{\"status\":" + this.status + ",\"message\":" + this.message + ",\"keepCallback\":" + this.keepCallback + "}"; } - + public String toSuccessCallbackString(String callbackId) { - return "cordova.callbackSuccess('" + callbackId + "'," + this.getJSONString() + ");"; + return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");"; } - + public String toErrorCallbackString(String callbackId) { - return "cordova.callbackError('" + callbackId + "', " + this.getJSONString() + ");"; + return "cordova.callbackError('"+callbackId+"', " + this.getJSONString()+ ");"; } - + public static String[] StatusMessages = new String[] { - "No result", - "OK", - "Class not found", - "Illegal access", - "Instantiation error", - "Malformed url", - "IO error", - "Invalid action", - "JSON error", - "Error" + "No result", + "OK", + "Class not found", + "Illegal access", + "Instantiation error", + "Malformed url", + "IO error", + "Invalid action", + "JSON error", + "Error" }; - + public enum Status { NO_RESULT, OK,