diff --git a/README.md b/README.md index 907f8cf..2e6813d 100644 --- a/README.md +++ b/README.md @@ -119,10 +119,18 @@ Cancels the notification the given notification id. id: The notification id. ``` +### `cancelwithcallback(int id, Function success, Function failure)` -### `cancelAll()` +Cancels the notification the given notification id. `success` and `failure` refer to function callbacks. `failure` will trigger if the cancellation fails, `success` will trigger if the cancellation succeeds. -Cancels all notifications. +``` + id: The notification id. +``` + + +### `cancelAll(Function success, Function failure)` + +Cancels all notifications. `success` and `failure` refer to function callbacks. `failure` will trigger if any one of the cancellation operations, which may be a partial success. `success` will only trigger with complete success. ### `setApplicationBadge(int value)` diff --git a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmHelper.java b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmHelper.java index 4b3f4a9..e889999 100644 --- a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmHelper.java +++ b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmHelper.java @@ -34,11 +34,11 @@ public void onCreate(Bundle savedInstanceState) { int notificationId = 0; // Default Id try { notificationId = bundle.getInt(AlarmReceiver.NOTIFICATION_ID); - Log.d("AlarmHelper", "Opening Activity with: " + notificationId); + Log.d(LocalNotification.TAG, "Opening Activity with: " + notificationId); } catch (Exception e) { try { notificationId = Integer.parseInt(bundle.getString(AlarmReceiver.NOTIFICATION_ID)); - Log.d("AlarmHelper", "Opening Activity with: " + notificationId); + Log.d(LocalNotification.TAG, "Opening Activity with: " + notificationId); } catch (Exception e2) { } } @@ -87,6 +87,7 @@ public boolean cancelAlarm(String notificationId) { try { getAlarmManager().cancel(pi); } catch (Exception e) { + Log.e(LocalNotification.TAG, "Exception: " + e); return false; } return true; @@ -97,6 +98,8 @@ public boolean cancelAlarm(String notificationId) { */ public boolean cancelAll(SharedPreferences alarmSettings) { Set alarmIds = alarmSettings.getAll().keySet(); + + Log.d(LocalNotification.TAG, "Number of alarmIds: " + alarmIds.size()); for (String alarmId : alarmIds) { Log.d(LocalNotification.TAG, "Canceling notification with id: " + alarmId); diff --git a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmOptions.java b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmOptions.java index 71127bb..2cb98a2 100644 --- a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmOptions.java +++ b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmOptions.java @@ -7,6 +7,8 @@ import org.json.JSONArray; import org.json.JSONObject; +import android.util.Log; + /** * Class that helps to store the options that can be specified per alarm. * @@ -41,23 +43,10 @@ public AlarmOptions(JSONArray options, Context context) { * JSON Array containing the list options. */ public void parseOptions(JSONArray optionsArr, Context context) { - final JSONObject options = optionsArr.optJSONObject(0); + final JSONObject options = optionsArr.optJSONObject(1); if (options != null) { - // Parse string representing the date - String textDate = options.optString("date"); - if (!"".equals(textDate)) { - String[] datePart = textDate.split("/"); - int month = Integer.parseInt(datePart[0]); - int day = Integer.parseInt(datePart[1]); - int year = Integer.parseInt(datePart[2]); - int hour = Integer.parseInt(datePart[3]); - int min = Integer.parseInt(datePart[4]); - - cal.set(year, month, day, hour, min); - } - String optString = options.optString("message"); if (!"".equals(optString)) { String lines[] = optString.split("\\r?\\n"); @@ -73,6 +62,7 @@ public void parseOptions(JSONArray optionsArr, Context context) { this.icon = android.R.drawable.btn_star_big_on; } + this.alarmTicker = options.optString("ticker"); this.alarmTicker = options.optString("ticker"); this.repeatDaily = options.optBoolean("repeatDaily"); this.notificationId = options.optString("id"); @@ -80,39 +70,39 @@ public void parseOptions(JSONArray optionsArr, Context context) { } public Calendar getCal() { - return cal; + return cal; } public void setCal(Calendar cal) { - this.cal = cal; + this.cal = cal; } public String getAlarmTitle() { - return alarmTitle; + return alarmTitle; } public void setAlarmTitle(String alarmTitle) { - this.alarmTitle = alarmTitle; + this.alarmTitle = alarmTitle; } public String getAlarmSubTitle() { - return alarmSubTitle; + return alarmSubTitle; } public void setAlarmSubTitle(String alarmSubTitle) { - this.alarmSubTitle = alarmSubTitle; + this.alarmSubTitle = alarmSubTitle; } public String getAlarmTicker() { - return alarmTicker; + return alarmTicker; } public void setAlarmTicker(String alarmTicker) { - this.alarmTicker = alarmTicker; + this.alarmTicker = alarmTicker; } public boolean isRepeatDaily() { - return repeatDaily; + return repeatDaily; } public int getIcon() { return this.icon; } @@ -120,15 +110,15 @@ public boolean isRepeatDaily() { public void setIcon(int icon) { this.icon = icon; } public void setRepeatDaily(boolean repeatDaily) { - this.repeatDaily = repeatDaily; + this.repeatDaily = repeatDaily; } public String getNotificationId() { - return notificationId; + return notificationId; } public void setNotificationId(String notificationId) { - this.notificationId = notificationId; + this.notificationId = notificationId; } } diff --git a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmReceiver.java b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmReceiver.java index df02eda..e010346 100644 --- a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmReceiver.java +++ b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmReceiver.java @@ -9,6 +9,8 @@ import android.os.Bundle; import android.util.Log; +import android.content.SharedPreferences; + /** * The alarm receiver is triggered when a scheduled alarm is fired. This class * reads the information in the intent and displays this information in the @@ -31,7 +33,7 @@ public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Log.d("AlarmReceiver", "AlarmReceiver invoked!"); + Log.d(LocalNotification.TAG, "AlarmReceiver invoked!"); Bundle bundle = intent.getExtras(); NotificationManager notificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); @@ -79,5 +81,18 @@ public void onReceive(Context context, Intent intent) { // Send JS a message LocalNotification.getCordovaWebView().sendJavascript("cordova.fireDocumentEvent('receivedLocalNotification', { active : true, notificationId : " + notificationId + " })"); } + + try { + String strnotifid = "" + notificationId; + context.getApplicationContext() + .getSharedPreferences(LocalNotification.TAG, Context.MODE_PRIVATE) + .edit() + .remove(strnotifid) + .commit(); + Log.d(LocalNotification.TAG, "Notification unpersisted: " + notificationId); + } catch (Exception e) { + Log.e(LocalNotification.TAG, "Failure to unpersist: " + e); + } + } } diff --git a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmRestoreOnBoot.java b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmRestoreOnBoot.java index 0957452..d9d1fca 100644 --- a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmRestoreOnBoot.java +++ b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/AlarmRestoreOnBoot.java @@ -22,6 +22,7 @@ public class AlarmRestoreOnBoot extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { + // Obtain alarm details form Shared Preferences SharedPreferences alarmSettings = context.getSharedPreferences(LocalNotification.TAG, Context.MODE_PRIVATE); final AlarmHelper alarm = new AlarmHelper(); @@ -34,22 +35,54 @@ public void onReceive(Context context, Intent intent) { */ for (String alarmId : allAlarms.keySet()) { try { - JSONArray alarmDetails = new JSONArray(alarmSettings.getString(alarmId, "")); - AlarmOptions options = new AlarmOptions(alarmDetails, context); - - alarm.addAlarm(options.getAlarmTitle(), - options.getAlarmSubTitle(), - options.getAlarmTicker(), - options.getNotificationId(), - options.getIcon(), - options.getCal().getTimeInMillis()); - - } catch (JSONException e) { - Log.d(LocalNotification.TAG, - "AlarmRestoreOnBoot: Error while restoring alarm details after reboot: " + e.toString()); + JSONArray args = new JSONArray(alarmSettings.getString(alarmId, "")); // second parameter is default valu + Log.d(LocalNotification.TAG, "alarmDetails in AlarmRestoreOnBoot.onReceive: " + args.toString()); + + //long seconds = System.currentTimeMillis() + (args.getJSONObject(1).getLong("seconds") * 1000); + long seconds = args.getJSONObject(1).getLong("seconds"); + String title, ticker, icon, message; + int iconResource = android.R.drawable.btn_star_big_on; + + title = ticker = icon = message = ""; + try { + title = args.getJSONObject(1).getString("title"); + } catch (Exception e){ + title = "Notification"; + } + try { + message = args.getJSONObject(1).getString("message"); + } catch (Exception e){ + message = "Notification message"; + } + try { + ticker = args.getJSONObject(1).getString("ticker"); + } catch (Exception e) { + ticker = message; + } + try { + icon = args.getJSONObject(1).getString("icon"); + } catch (Exception e) {} + + + if (icon != "") { + try { + iconResource = android.R.drawable.btn_star_big_on; + //iconResource = cordova.getActivity().getResources().getIdentifier(icon, "drawable", cordova.getActivity().getPackageName()); + } catch(Exception e) { + Log.e(LocalNotification.TAG, "The icon resource couldn't be found. Taking default icon."); + } + } + + alarm.addAlarm(title, message, ticker, alarmId, iconResource, seconds); + + + } catch (Exception e) { + Log.e(LocalNotification.TAG, "AlarmRestoreOnBoot: Error while restoring alarm details after reboot: " + e.toString()); } - Log.d(LocalNotification.TAG, "AlarmRestoreOnBoot: Successfully restored alarms upon reboot"); + Log.d(LocalNotification.TAG, "AlarmRestoreOnBoot: Successfully restored alarms id upon reboot: " + alarmId); + } + Log.d(LocalNotification.TAG, "AlarmRestoreOnBoot: Successfully restored alarms upon reboot"); } } diff --git a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/LocalNotification.java b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/LocalNotification.java index 5c2a5f1..9776025 100644 --- a/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/LocalNotification.java +++ b/platforms/android/src/jp/wizcorp/phonegap/plugin/localNotification/LocalNotification.java @@ -8,6 +8,7 @@ import android.content.Context; import android.util.Log; +import java.util.Set; import java.lang.Exception; @@ -51,17 +52,18 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo String alarmId; this.alarm = new AlarmHelper(); this.alarm.setContext(cordova.getActivity().getApplicationContext()); - - try { - alarmId = args.getString(0); - } catch (Exception e) { - Log.d(TAG, "Unable to process alarm with string id: " + args.getString(0)); - callbackContext.error("Cannot use string for notification id."); - return true; - } if (action.equalsIgnoreCase("addNotification")) { + try { + alarmId = args.getString(0); //getString coerces if necessary, throws JSONexception if not + } catch (Exception e) { + Log.e(TAG, "No ID provided."); + callbackContext.error("No ID provided."); + return true; + } + + try { long seconds = System.currentTimeMillis() + (args.getJSONObject(1).getLong("seconds") * 1000); String title, ticker, icon; @@ -86,7 +88,9 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo Log.e(TAG, "The icon resource couldn't be found. Taking default icon."); } } - + + args.getJSONObject(1).put("seconds", seconds); + persistAlarm(alarmId, args); return this.add(callbackContext, title == "" ? "Notification" : title, args.getJSONObject(1).getString("message"), ticker == "" ? args.getJSONObject(1).getString("message") : ticker, @@ -96,14 +100,34 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo } } else if (action.equalsIgnoreCase("cancelNotification")) { - unpersistAlarm(alarmId); - return this.cancelNotification(callbackContext, alarmId); + + try { + alarmId = args.getString(0); //getString coerces if necessary, throws JSONexception if not + } catch (Exception e) { + Log.e(TAG, "No ID provided."); + callbackContext.error("No ID provided."); + return true; + } + + boolean result = cancelNotification(callbackContext, alarmId); + + if (result) { + callbackContext.success(); + unpersistAlarm(alarmId); + return true; + } else { + callbackContext.error("Cancel notification failed, ID: " + alarmId); + return false; + } + + } else if (action.equalsIgnoreCase("cancelAllNotifications")) { - unpersistAlarmAll(); + Log.d(TAG, "cancelAllNotifications called"); return this.cancelAllNotifications(callbackContext); } - - return false; + + Log.e(TAG, "Didn't match any action, returning false"); + return false; // Returning false results in a "MethodNotFound" error. } /** @@ -148,15 +172,8 @@ public Boolean add(CallbackContext callbackContext, String alarmTitle, String al public Boolean cancelNotification(CallbackContext callbackContext, String notificationId) { Log.d(TAG, "cancelNotification: Canceling event with id: " + notificationId); - boolean result = alarm.cancelAlarm(notificationId); - - if (result) { - callbackContext.success(); - return true; - } else { - callbackContext.error("Cancel notification failed."); - return false; - } + return alarm.cancelAlarm(notificationId); + } /** @@ -172,6 +189,29 @@ public Boolean cancelAllNotifications(CallbackContext callbackContext) { * all our alarms to loop through these alarms and unregister them one * by one. */ + + Set alarmIds = cordova.getActivity().getApplicationContext().getSharedPreferences(TAG, Context.MODE_PRIVATE).getAll().keySet(); + + Log.d(LocalNotification.TAG, "Number of alarmIds: " + alarmIds.size()); + + boolean outcome = true; + + for (String alarmId : alarmIds) { + Log.d(LocalNotification.TAG, "Canceling notification with id: " + alarmId); + boolean result = this.cancelNotification(callbackContext, alarmId); + if (result) { + unpersistAlarm(alarmId); + } + else { + Log.e(LocalNotification.TAG, "Failed to cancel notification with id: " + alarmId); + callbackContext.error("Failed to cancel all notifications. Failed to cancel notification with id: " + alarmId); + return false; + } + } + callbackContext.success(); + return true; + + /* boolean result = alarm.cancelAll(cordova.getActivity() .getApplicationContext() .getSharedPreferences(TAG, Context.MODE_PRIVATE)); @@ -183,6 +223,7 @@ public Boolean cancelAllNotifications(CallbackContext callbackContext) { callbackContext.error("Cancel all notifications failed."); return false; } + */ } public static CordovaWebView getCordovaWebView() { diff --git a/www/phonegap/plugin/localNotification/localNotification.js b/www/phonegap/plugin/localNotification/localNotification.js index 9713b4b..51fcf7a 100755 --- a/www/phonegap/plugin/localNotification/localNotification.js +++ b/www/phonegap/plugin/localNotification/localNotification.js @@ -24,9 +24,13 @@ LocalNotification.prototype.add = function (id, options, success, failure) { LocalNotification.prototype.cancel = function (id) { exec(null, null, "LocalNotification", "cancelNotification", [id]); }; + +LocalNotification.prototype.cancelwithcallback = function (id, success, failure) { + exec(success, failure, "LocalNotification", "cancelNotification", [id]); + }; -LocalNotification.prototype.cancelAll = function () { - exec(null, null,"LocalNotification", "cancelAllNotifications", []); +LocalNotification.prototype.cancelAll = function (success, failure) { + exec(success, failure,"LocalNotification", "cancelAllNotifications", []); }; LocalNotification.prototype.queue = function (id, options, success, failure) {