Kaynağa Gözat

Add back all querry methods on Android

Sebastián Katzer 8 yıl önce
ebeveyn
işleme
c967ea57b5

+ 198 - 305
src/android/LocalNotification.java

@@ -35,6 +35,7 @@ import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import de.appplant.cordova.plugin.notification.Manager;
 import de.appplant.cordova.plugin.notification.Notification;
@@ -42,6 +43,9 @@ import de.appplant.cordova.plugin.notification.Options;
 import de.appplant.cordova.plugin.notification.Request;
 import de.appplant.cordova.plugin.notification.action.ActionGroup;
 
+import static de.appplant.cordova.plugin.notification.Notification.Type.SCHEDULED;
+import static de.appplant.cordova.plugin.notification.Notification.Type.TRIGGERED;
+
 /**
  * This plugin utilizes the Android AlarmManager in combination with local
  * notifications. When a local notification is scheduled the alarm manager takes
@@ -157,58 +161,46 @@ public class LocalNotification extends CordovaPlugin {
                 //     update(args);
                 //     command.success();
                 // } else
-                // if (action.equals("cancel")) {
-                //     cancel(args);
-                //     command.success();
-                // } else
-                // if (action.equals("cancelAll")) {
-                //     cancelAll();
-                //     command.success();
-                // } else
-                // if (action.equals("clear")) {
-                //     clear(args);
-                //     command.success();
-                // } else
+                if (action.equals("cancel")) {
+                    cancel(args);
+                    command.success();
+                } else
+                if (action.equals("cancelAll")) {
+                    cancelAll();
+                    command.success();
+                } else
+                if (action.equals("clear")) {
+                    clear(args);
+                    command.success();
+                } else
                 if (action.equals("clearAll")) {
                     clearAll();
                     command.success();
+                } else
+                if (action.equals("type")) {
+                    type(args.optInt(0), command);
+                } else
+                if (action.equals("ids")) {
+                    ids(command);
+                } else
+                if (action.equals("scheduledIds")) {
+                    scheduledIds(command);
+                } else
+                if (action.equals("triggeredIds")) {
+                    triggeredIds(command);
+                } else
+                if (action.equals("notification")) {
+                    notification(args.optInt(0), command);
+                } else
+                if (action.equals("notifications")) {
+                    notifications(args, command);
+                } else
+                if (action.equals("scheduledNotifications")) {
+                    scheduledNotifications(command);
+                } else
+                if (action.equals("triggeredNotifications")) {
+                    triggeredNotifications(command);
                 }
-                // if (action.equals("isPresent")) {
-                //     isPresent(args.optInt(0), command);
-                // } else
-                // if (action.equals("isScheduled")) {
-                //     isScheduled(args.optInt(0), command);
-                // } else
-                // if (action.equals("isTriggered")) {
-                //     isTriggered(args.optInt(0), command);
-                // } else
-                // if (action.equals("getAllIds")) {
-                //     getAllIds(command);
-                // } else
-                // if (action.equals("getScheduledIds")) {
-                //     getScheduledIds(command);
-                // } else
-                // if (action.equals("getTriggeredIds")) {
-                //     getTriggeredIds(command);
-                // } else
-                // if (action.equals("getSingle")) {
-                //     getSingle(args, command);
-                // } else
-                // if (action.equals("getSingleScheduled")) {
-                //     getSingleScheduled(args, command);
-                // } else
-                // if (action.equals("getSingleTriggered")) {
-                //     getSingleTriggered(args, command);
-                // } else
-                // if (action.equals("getAll")) {
-                //     getAll(args, command);
-                // } else
-                // if (action.equals("getScheduled")) {
-                //     getScheduled(args, command);
-                // } else
-                // if (action.equals("getTriggered")) {
-                //     getTriggered(args, command);
-                // }
             }
         });
 
@@ -292,7 +284,9 @@ public class LocalNotification extends CordovaPlugin {
             Notification notification =
                     mgr.schedule(request, TriggerReceiver.class);
 
-            fireEvent("add", notification);
+            if (notification != null) {
+                fireEvent("add", notification);
+            }
         }
     }
 
@@ -317,53 +311,51 @@ public class LocalNotification extends CordovaPlugin {
     //     }
     // }
 
-    // /**
-    //  * Cancel multiple local notifications.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  */
-    // private void cancel (JSONArray ids) {
-    //     for (int i = 0; i < ids.length(); i++) {
-    //         int id = ids.optInt(i, 0);
+    /**
+     * Cancel multiple local notifications.
+     *
+     * @param ids Set of local notification IDs
+     */
+    private void cancel (JSONArray ids) {
+        for (int i = 0; i < ids.length(); i++) {
+            int id = ids.optInt(i, 0);
 
-    //         Notification notification =
-    //                 getNotMgr().cancel(id);
+            Notification notification =
+                    getNotMgr().cancel(id);
 
-    //         if (notification == null)
-    //             continue;
+            if (notification == null)
+                continue;
 
-    //         fireEvent("cancel", notification);
-    //     }
-    // }
+            fireEvent("cancel", notification);
+        }
+    }
 
-    // /**
-    //  * Cancel all scheduled notifications.
-    //  */
-    // private void cancelAll() {
-    //     getNotMgr().cancelAll();
-    //     fireEvent("cancelall");
-    // }
+    /**
+     * Cancel all scheduled notifications.
+     */
+    private void cancelAll() {
+        getNotMgr().cancelAll();
+        fireEvent("cancelall");
+    }
 
-    // /**
-    //  * Clear multiple local notifications without canceling them.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  */
-    // private void clear(JSONArray ids){
-    //     for (int i = 0; i < ids.length(); i++) {
-    //         int id = ids.optInt(i, 0);
+    /**
+     * Clear multiple local notifications without canceling them.
+     *
+     * @param ids Set of local notification IDs
+     */
+    private void clear(JSONArray ids){
+        for (int i = 0; i < ids.length(); i++) {
+            int id = ids.optInt(i, 0);
 
-    //         Notification notification =
-    //                 getNotMgr().clear(id);
+            Notification notification =
+                    getNotMgr().clear(id);
 
-    //         if (notification == null)
-    //             continue;
+            if (notification == null)
+                continue;
 
-    //         fireEvent("clear", notification);
-    //     }
-    // }
+            fireEvent("clear", notification);
+        }
+    }
 
     /**
      * Clear all triggered notifications without canceling them.
@@ -373,222 +365,124 @@ public class LocalNotification extends CordovaPlugin {
         fireEvent("clearall");
     }
 
-    // /**
-    //  * If a notification with an ID is present.
-    //  *
-    //  * @param id
-    //  *      Notification ID
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void isPresent (int id, CallbackContext command) {
-    //     boolean exist = getNotMgr().exist(id);
-
-    //     PluginResult result = new PluginResult(
-    //             PluginResult.Status.OK, exist);
-
-    //     command.sendPluginResult(result);
-    // }
-
-    // /**
-    //  * If a notification with an ID is scheduled.
-    //  *
-    //  * @param id
-    //  *      Notification ID
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void isScheduled (int id, CallbackContext command) {
-    //     boolean exist = getNotMgr().exist(
-    //             id, Notification.Type.SCHEDULED);
-
-    //     PluginResult result = new PluginResult(
-    //             PluginResult.Status.OK, exist);
-
-    //     command.sendPluginResult(result);
-    // }
-
-    // /**
-    //  * If a notification with an ID is triggered.
-    //  *
-    //  * @param id
-    //  *      Notification ID
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void isTriggered (int id, CallbackContext command) {
-    //     boolean exist = getNotMgr().exist(
-    //             id, Notification.Type.TRIGGERED);
-
-    //     PluginResult result = new PluginResult(
-    //             PluginResult.Status.OK, exist);
-
-    //     command.sendPluginResult(result);
-    // }
-
-    // /**
-    //  * Set of IDs from all existent notifications.
-    //  *
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getAllIds (CallbackContext command) {
-    //     List<Integer> ids = getNotMgr().getIds();
-
-    //     command.success(new JSONArray(ids));
-    // }
-
-    // /**
-    //  * Set of IDs from all scheduled notifications.
-    //  *
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getScheduledIds (CallbackContext command) {
-    //     List<Integer> ids = getNotMgr().getIdsByType(
-    //             Notification.Type.SCHEDULED);
-
-    //     command.success(new JSONArray(ids));
-    // }
-
-    // /**
-    //  * Set of IDs from all triggered notifications.
-    //  *
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getTriggeredIds (CallbackContext command) {
-    //     List<Integer> ids = getNotMgr().getIdsByType(
-    //             Notification.Type.TRIGGERED);
-
-    //     command.success(new JSONArray(ids));
-    // }
-
-    // /**
-    //  * Options from local notification.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getSingle (JSONArray ids, CallbackContext command) {
-    //     getOptions(ids.optString(0), Notification.Type.ALL, command);
-    // }
-
-    // /**
-    //  * Options from scheduled notification.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getSingleScheduled (JSONArray ids, CallbackContext command) {
-    //     getOptions(ids.optString(0), Notification.Type.SCHEDULED, command);
-    // }
-
-    // /**
-    //  * Options from triggered notification.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getSingleTriggered (JSONArray ids, CallbackContext command) {
-    //     getOptions(ids.optString(0), Notification.Type.TRIGGERED, command);
-    // }
+    /**
+     * Get the type of the notification (unknown, scheduled, triggered).
+     *
+     * @param id      The ID of the notification to check.
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void type (int id, CallbackContext command) {
+        Notification toast = getNotMgr().get(id);
 
-    // /**
-    //  * Set of options from local notification.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getAll (JSONArray ids, CallbackContext command) {
-    //     getOptions(ids, Notification.Type.ALL, command);
-    // }
+        if (toast == null) {
+            command.success("unknown");
+            return;
+        }
 
-    // /**
-    //  * Set of options from scheduled notifications.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getScheduled (JSONArray ids, CallbackContext command) {
-    //     getOptions(ids, Notification.Type.SCHEDULED, command);
-    // }
+        switch (toast.getType()) {
+            case SCHEDULED:
+                command.success("scheduled");
+                break;
+            case TRIGGERED:
+                command.success("triggered");
+                break;
+            default:
+                command.success("unknown");
+                break;
+        }
+    }
 
-    // /**
-    //  * Set of options from triggered notifications.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getTriggered (JSONArray ids, CallbackContext command) {
-    //     getOptions(ids, Notification.Type.TRIGGERED, command);
-    // }
+    /**
+     * Set of IDs from all existent notifications.
+     *
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void ids (CallbackContext command) {
+        List<Integer> ids = getNotMgr().getIds();
+        command.success(new JSONArray(ids));
+    }
 
-    // /**
-    //  * Options from local notification.
-    //  *
-    //  * @param id
-    //  *      Set of local notification IDs
-    //  * @param type
-    //  *      The local notification life cycle type
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getOptions (String id, Notification.Type type,
-    //                          CallbackContext command) {
+    /**
+     * Set of IDs from all scheduled notifications.
+     *
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void scheduledIds (CallbackContext command) {
+        List<Integer> ids = getNotMgr().getIdsByType(SCHEDULED);
+        command.success(new JSONArray(ids));
+    }
 
-    //     JSONArray ids = new JSONArray().put(id);
-    //     PluginResult result;
+    /**
+     * Set of IDs from all triggered notifications.
+     *
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void triggeredIds (CallbackContext command) {
+        List<Integer> ids = getNotMgr().getIdsByType(TRIGGERED);
+        command.success(new JSONArray(ids));
+    }
 
-    //     List<JSONObject> options =
-    //             getNotMgr().getOptionsBy(type, toList(ids));
+    /**
+     * Options from local notification.
+     *
+     * @param id      The ID of the notification.
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void notification (int id, CallbackContext command) {
+        Options options = getNotMgr().getOptions(id);
 
-    //     if (options.isEmpty()) {
-    //         // Status.NO_RESULT led to no callback invocation :(
-    //         // Status.OK        led to no NPE and crash
-    //         result = new PluginResult(PluginResult.Status.NO_RESULT);
-    //     } else {
-    //         result = new PluginResult(PluginResult.Status.OK, options.get(0));
-    //     }
+        if (options != null) {
+            command.success(options.getDict());
+        } else {
+            command.success();
+        }
+    }
 
-    //     command.sendPluginResult(result);
-    // }
+    /**
+     * Set of options from local notification.
+     *
+     * @param ids     Set of local notification IDs.
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void notifications (JSONArray ids, CallbackContext command) {
+        List<JSONObject> options;
 
-    // /**
-    //  * Set of options from local notifications.
-    //  *
-    //  * @param ids
-    //  *      Set of local notification IDs
-    //  * @param type
-    //  *      The local notification life cycle type
-    //  * @param command
-    //  *      The callback context used when calling back into JavaScript.
-    //  */
-    // private void getOptions (JSONArray ids, Notification.Type type,
-    //                          CallbackContext command) {
+        if (ids.length() == 0) {
+            options = getNotMgr().getOptions();
+        } else {
+            options = getNotMgr().getOptionsById(toList(ids));
+        }
 
-    //     List<JSONObject> options;
+        command.success(new JSONArray(options));
+    }
 
-    //     if (ids.length() == 0) {
-    //         options = getNotMgr().getOptionsByType(type);
-    //     } else {
-    //         options = getNotMgr().getOptionsBy(type, toList(ids));
-    //     }
+    /**
+     * Set of options from scheduled notifications.
+     *
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void scheduledNotifications (CallbackContext command) {
+        List<JSONObject> options = getNotMgr().getOptionsByType(SCHEDULED);
+        command.success(new JSONArray(options));
+    }
 
-    //     command.success(new JSONArray(options));
-    // }
+    /**
+     * Set of options from triggered notifications.
+     *
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     */
+    private void triggeredNotifications (CallbackContext command) {
+        List<JSONObject> options = getNotMgr().getOptionsByType(TRIGGERED);
+        command.success(new JSONArray(options));
+    }
 
     /**
      * Call all pending callbacks after the deviceready event has been fired.
@@ -680,21 +574,20 @@ public class LocalNotification extends CordovaPlugin {
         });
     }
 
-    // /**
-    //  * Convert JSON array of integers to List.
-    //  *
-    //  * @param ary
-    //  *      Array of integers
-    //  */
-    // private List<Integer> toList (JSONArray ary) {
-    //     ArrayList<Integer> list = new ArrayList<Integer>();
+    /**
+     * Convert JSON array of integers to List.
+     *
+     * @param ary Array of integers.
+     */
+    private List<Integer> toList (JSONArray ary) {
+        List<Integer> list = new ArrayList<Integer>();
 
-    //     for (int i = 0; i < ary.length(); i++) {
-    //         list.add(ary.optInt(i));
-    //     }
+        for (int i = 0; i < ary.length(); i++) {
+            list.add(ary.optInt(i));
+        }
 
-    //     return list;
-    // }
+        return list;
+    }
 
     /**
      * Notification manager instance.

+ 13 - 5
src/android/notification/Builder.java

@@ -35,6 +35,9 @@ import java.util.Random;
 
 import de.appplant.cordova.plugin.notification.action.Action;
 
+import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
+import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
+
 /**
  * Builder class for local notifications. Build fully configured local
  * notification specified by JSON object passed from JS side.
@@ -47,6 +50,9 @@ public final class Builder {
     // Notification options passed by JS
     private final Options options;
 
+    // To generate unique request codes
+    private final Random random = new Random();
+
     // Receiver to handle the clear event
     private Class<?> clearReceiver;
 
@@ -283,8 +289,10 @@ public final class Builder {
                 .setAction(options.getIdentifier())
                 .putExtra(Notification.EXTRA_ID, options.getId());
 
+        int reqCode = random.nextInt();
+
         PendingIntent deleteIntent = PendingIntent.getBroadcast(
-                context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+                context, reqCode, intent, FLAG_UPDATE_CURRENT);
 
         builder.setDeleteIntent(deleteIntent);
     }
@@ -307,10 +315,10 @@ public final class Builder {
                 .putExtra(Options.EXTRA_LAUNCH, options.isLaunchingApp())
                 .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
 
-        int reqCode = new Random().nextInt();
+        int reqCode = random.nextInt();
 
         PendingIntent contentIntent = PendingIntent.getActivity(
-                context, reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+                context, reqCode, intent, FLAG_UPDATE_CURRENT);
 
         builder.setContentIntent(contentIntent);
     }
@@ -354,10 +362,10 @@ public final class Builder {
                 .putExtra(Options.EXTRA_LAUNCH, action.isLaunchingApp())
                 .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
 
-        int reqCode = new Random().nextInt();
+        int reqCode = random.nextInt();
 
         return PendingIntent.getActivity(
-                context, reqCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+                context, reqCode, intent, FLAG_CANCEL_CURRENT);
     }
 
 }

+ 161 - 215
src/android/notification/Manager.java

@@ -25,17 +25,23 @@ import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.service.notification.StatusBarNotification;
 import android.support.v4.app.NotificationManagerCompat;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import de.appplant.cordova.plugin.badge.BadgeImpl;
 
 import static android.os.Build.VERSION.SDK_INT;
 import static android.os.Build.VERSION_CODES.O;
 import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_DEFAULT;
-import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY;
+import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY_ID;
+import static de.appplant.cordova.plugin.notification.Notification.Type.TRIGGERED;
 
 /**
  * Central way to access all or single local notifications set by specific
@@ -142,262 +148,202 @@ public final class Manager {
     //     return schedule(options, receiver);
     // }
 
-    // /**
-    //  * Clear local notification specified by ID.
-    //  *
-    //  * @param id The notification ID.
-    //  */
-    // public Notification clear (int id) {
-    //     Notification notification = get(id);
+    /**
+     * Clear local notification specified by ID.
+     *
+     * @param id The notification ID.
+     */
+    public Notification clear (int id) {
+        Notification toast = get(id);
 
-    //     if (notification != null) {
-    //         notification.clear();
-    //     }
+        if (toast != null) {
+            toast.clear();
+        }
 
-    //     return notification;
-    // }
+        return toast;
+    }
 
     /**
      * Clear all local notifications.
      */
     public void clearAll () {
+        List<Notification> toasts = getByType(TRIGGERED);
+
+        for (Notification toast : toasts) {
+            toast.clear();
+        }
+
         getNotCompMgr().cancelAll();
         setBadge(0);
     }
 
-    // /**
-    //  * Clear local notification specified by ID.
-    //  *
-    //  * @param id
-    //  *      The notification ID
-    //  */
-    // public Notification cancel (int id) {
-    //     Notification notification = get(id);
-
-    //     if (notification != null) {
-    //         notification.cancel();
-    //     }
-
-    //     return notification;
-    // }
-
-    // /**
-    //  * Cancel all local notifications.
-    //  */
-    // public void cancelAll () {
-    //     List<Notification> notifications = getAll();
-
-    //     for (Notification notification : notifications) {
-    //         notification.cancel();
-    //     }
-
-    //     getNotCompMgr().cancelAll();
-    // }
-
-    // /**
-    //  * All local notifications IDs.
-    //  */
-    // public List<Integer> getIds() {
-    //     Set<String> keys = getPrefs().getAll().keySet();
-    //     ArrayList<Integer> ids = new ArrayList<Integer>();
-
-    //     for (String key : keys) {
-    //         try {
-    //             ids.add(Integer.parseInt(key));
-    //         } catch (NumberFormatException e) {
-    //             e.printStackTrace();
-    //         }
-    //     }
-
-    //     return ids;
-    // }
-
-    // /**
-    //  * All local notification IDs for given type.
-    //  *
-    //  * @param type
-    //  *      The notification life cycle type
-    //  */
-    // public List<Integer> getIdsByType(Notification.Type type) {
-    //     List<Notification> notifications = getAll();
-    //     ArrayList<Integer> ids = new ArrayList<Integer>();
+    /**
+     * Clear local notification specified by ID.
+     *
+     * @param id The notification ID
+     */
+    public Notification cancel (int id) {
+        Notification toast = get(id);
 
-    //     for (Notification notification : notifications) {
-    //         if (notification.getType() == type) {
-    //             ids.add(notification.getId());
-    //         }
-    //     }
+        if (toast != null) {
+            toast.cancel();
+        }
 
-    //     return ids;
-    // }
+        return toast;
+    }
 
-    // /**
-    //  * List of local notifications with matching ID.
-    //  *
-    //  * @param ids
-    //  *      Set of notification IDs
-    //  */
-    // public List<Notification> getByIds(List<Integer> ids) {
-    //     ArrayList<Notification> notifications = new ArrayList<Notification>();
+    /**
+     * Cancel all local notifications.
+     */
+    public void cancelAll () {
+        List<Notification> notifications = getAll();
 
-    //     for (int id : ids) {
-    //         Notification notification = get(id);
+        for (Notification notification : notifications) {
+            notification.cancel();
+        }
 
-    //         if (notification != null) {
-    //             notifications.add(notification);
-    //         }
-    //     }
+        getNotCompMgr().cancelAll();
+        setBadge(0);
+    }
 
-    //     return notifications;
-    // }
+    /**
+     * All local notifications IDs.
+     */
+    public List<Integer> getIds() {
+        Set<String> keys = getPrefs().getAll().keySet();
+        List<Integer> ids = new ArrayList<Integer>();
+
+        for (String key : keys) {
+            try {
+                ids.add(Integer.parseInt(key));
+            } catch (NumberFormatException e) {
+                e.printStackTrace();
+            }
+        }
 
-    // /**
-    //  * List of all local notification.
-    //  */
-    // public List<Notification> getAll() {
-    //     return getByIds(getIds());
-    // }
+        return ids;
+    }
 
-    // /**
-    //  * List of local notifications from given type.
-    //  *
-    //  * @param type
-    //  *      The notification life cycle type
-    //  */
-    // public List<Notification> getByType(Notification.Type type) {
-    //     List<Notification> notifications = getAll();
-    //     ArrayList<Notification> list = new ArrayList<Notification>();
+    /**
+     * All local notification IDs for given type.
+     *
+     * @param type The notification life cycle type
+     */
+    public List<Integer> getIdsByType(Notification.Type type) {
 
-    //     if (type == Notification.Type.ALL)
-    //         return notifications;
+        if (type == Notification.Type.ALL)
+            return getIds();
 
-    //     for (Notification notification : notifications) {
-    //         if (notification.getType() == type) {
-    //             list.add(notification);
-    //         }
-    //     }
+        StatusBarNotification[] activeToasts = getNotMgr().getActiveNotifications();
+        List<Integer> activeIds = new ArrayList<Integer>();
 
-    //     return list;
-    // }
+        for (StatusBarNotification toast : activeToasts) {
+            activeIds.add(toast.getId());
+        }
 
-    // /**
-    //  * List of local notifications with matching ID from given type.
-    //  *
-    //  * @param type
-    //  *      The notification life cycle type
-    //  * @param ids
-    //  *      Set of notification IDs
-    //  */
-    // @SuppressWarnings("UnusedDeclaration")
-    // public List<Notification> getBy(Notification.Type type, List<Integer> ids) {
-    //     ArrayList<Notification> notifications = new ArrayList<Notification>();
+        if (type == TRIGGERED)
+            return activeIds;
 
-    //     for (int id : ids) {
-    //         Notification notification = get(id);
+        List<Integer> ids = getIds();
+        ids.removeAll(activeIds);
 
-    //         if (notification != null && notification.isScheduled()) {
-    //             notifications.add(notification);
-    //         }
-    //     }
+        return ids;
+    }
 
-    //     return notifications;
-    // }
+    /**
+     * List of local notifications with matching ID.
+     *
+     * @param ids Set of notification IDs.
+     */
+    private List<Notification> getByIds(List<Integer> ids) {
+        List<Notification> toasts = new ArrayList<Notification>();
 
-    // /**
-    //  * If a notification with an ID exists.
-    //  *
-    //  * @param id
-    //  *      Notification ID
-    //  */
-    // public boolean exist (int id) {
-    //     return get(id) != null;
-    // }
+        for (int id : ids) {
+            Notification toast = get(id);
 
-    // /**
-    //  * If a notification with an ID and type exists.
-    //  *
-    //  * @param id
-    //  *      Notification ID
-    //  * @param type
-    //  *      Notification type
-    //  */
-    // public boolean exist (int id, Notification.Type type) {
-    //     Notification notification = get(id);
+            if (toast != null) {
+                toasts.add(toast);
+            }
+        }
 
-    //     return notification != null && notification.getType() == type;
-    // }
+        return toasts;
+    }
 
-    // /**
-    //  * List of properties from all local notifications.
-    //  */
-    // public List<JSONObject> getOptions() {
-    //     return getOptionsById(getIds());
-    // }
+    /**
+     * List of all local notification.
+     */
+    public List<Notification> getAll() {
+        return getByIds(getIds());
+    }
 
-    // /**
-    //  * List of properties from local notifications with matching ID.
-    //  *
-    //  * @param ids
-    //  *      Set of notification IDs
-    //  */
-    // public List<JSONObject> getOptionsById(List<Integer> ids) {
-    //     ArrayList<JSONObject> options = new ArrayList<JSONObject>();
+    /**
+     * List of local notifications from given type.
+     *
+     * @param type The notification life cycle type
+     */
+    private List<Notification> getByType(Notification.Type type) {
 
-    //     for (int id : ids) {
-    //         Notification notification = get(id);
+        if (type == Notification.Type.ALL)
+            return getAll();
 
+        List<Integer> ids = getIdsByType(type);
 
-    //         if (notification != null) {
-    //             options.add(notification.getOptions().getDict());
-    //         }
-    //     }
+        return getByIds(ids);
+    }
 
-    //     return options;
-    // }
+    /**
+     * If a notification with an ID exists.
+     *
+     * @param id Notification ID
+     *
+     * @return true if found.
+     */
+    public boolean exist (int id) {
+        return get(id) != null;
+    }
 
-    // /**
-    //  * List of properties from all local notifications from given type.
-    //  *
-    //  * @param type
-    //  *      The notification life cycle type
-    //  */
-    // public List<JSONObject> getOptionsByType(Notification.Type type) {
-    //     ArrayList<JSONObject> options = new ArrayList<JSONObject>();
-    //     List<Notification> notifications = getByType(type);
+    /**
+     * List of properties from all local notifications.
+     */
+    public List<JSONObject> getOptions() {
+        return getOptionsById(getIds());
+    }
 
-    //     for (Notification notification : notifications) {
-    //         options.add(notification.getOptions().getDict());
-    //     }
+    /**
+     * List of properties from local notifications with matching ID.
+     *
+     * @param ids Set of notification IDs
+     */
+    public List<JSONObject> getOptionsById(List<Integer> ids) {
+        List<JSONObject> toasts = new ArrayList<JSONObject>();
 
-    //     return options;
-    // }
+        for (int id : ids) {
+            Options options = getOptions(id);
 
-    // /**
-    //  * List of properties from local notifications with matching ID from
-    //  * given type.
-    //  *
-    //  * @param type
-    //  *      The notification life cycle type
-    //  * @param ids
-    //  *      Set of notification IDs
-    //  */
-    // public List<JSONObject> getOptionsBy(Notification.Type type,
-    //                                      List<Integer> ids) {
+            if (options != null) {
+                toasts.add(options.getDict());
+            }
+        }
 
-    //     if (type == Notification.Type.ALL)
-    //         return getOptionsById(ids);
+        return toasts;
+    }
 
-    //     ArrayList<JSONObject> options = new ArrayList<JSONObject>();
-    //     List<Notification> notifications = getByIds(ids);
+    /**
+     * List of properties from all local notifications from given type.
+     *
+     * @param type
+     *      The notification life cycle type
+     */
+    public List<JSONObject> getOptionsByType(Notification.Type type) {
+        ArrayList<JSONObject> options = new ArrayList<JSONObject>();
+        List<Notification> notifications = getByType(type);
 
-    //     for (Notification notification : notifications) {
-    //         if (notification.getType() == type) {
-    //             options.add(notification.getOptions().getDict());
-    //         }
-    //     }
+        for (Notification notification : notifications) {
+            options.add(notification.getOptions().getDict());
+        }
 
-    //     return options;
-    // }
+        return options;
+    }
 
     /**
      * Get local notification options.
@@ -481,7 +427,7 @@ public final class Manager {
      * Shared private preferences for the application.
      */
     private SharedPreferences getPrefs () {
-        return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
+        return context.getSharedPreferences(PREF_KEY_ID, Context.MODE_PRIVATE);
     }
 
     /**

+ 48 - 74
src/android/notification/Notification.java

@@ -21,7 +21,6 @@
 
 package de.appplant.cordova.plugin.notification;
 
-
 import android.app.AlarmManager;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -30,6 +29,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.net.Uri;
+import android.service.notification.StatusBarNotification;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.util.ArraySet;
 import android.support.v4.util.Pair;
@@ -63,7 +63,10 @@ public final class Notification {
     public static final String EXTRA_ID = "NOTIFICATION_ID";
 
     // Key for private preferences
-    static final String PREF_KEY = "LocalNotification";
+    static final String PREF_KEY_ID = "NOTIFICATION_ID";
+
+    // Key for private preferences
+    private static final String PREF_KEY_PID = "NOTIFICATION_PID";
 
     // Application context passed by constructor
     private final Context context;
@@ -127,42 +130,21 @@ public final class Notification {
         return getOptions().getTrigger().has("every");
     }
 
-    // /**
-    //  * If the notification is scheduled.
-    //  */
-    // public boolean isScheduled () {
-    //     return isRepeating() || !wasInThePast();
-    // }
-
-    // /**
-    //  * If the notification is triggered.
-    //  */
-    // public boolean isTriggered () {
-    //     return wasInThePast();
-    // }
-
-    // /**
-    //  * If the notification is an update.
-    //  *
-    //  * @param keepFlag
-    //  *      Set to false to remove the flag from the option map
-    //  */
-    // protected boolean isUpdate (boolean keepFlag) {
-    //     boolean updated = options.getDict().optBoolean("updated", false);
-
-    //     if (!keepFlag) {
-    //         options.getDict().remove("updated");
-    //     }
-
-    //     return updated;
-    // }
-
-    // /**
-    //  * Notification type can be one of pending or scheduled.
-    //  */
-    // public Type getType () {
-    //     return isScheduled() ? Type.SCHEDULED : Type.TRIGGERED;
-    // }
+    /**
+     * Notification type can be one of triggered or scheduled.
+     */
+    public Type getType () {
+        StatusBarNotification[] toasts = getNotMgr().getActiveNotifications();
+        int id = getId();
+
+        for (StatusBarNotification toast : toasts) {
+            if (toast.getId() == id) {
+                return Type.TRIGGERED;
+            }
+        }
+
+        return Type.SCHEDULED;
+    }
 
     /**
      * Schedule the local notification.
@@ -172,8 +154,8 @@ public final class Notification {
      */
     void schedule(Request request, Class<?> receiver) {
         List<Pair<Date, Intent>> intents = new ArrayList<Pair<Date, Intent>>();
-        Set<String> ids = new ArraySet<String>();
-        AlarmManager mgr = getAlarmMgr();
+        Set<String> ids                  = new ArraySet<String>();
+        AlarmManager mgr                 = getAlarmMgr();
 
         do {
             Date date = request.getTriggerDate();
@@ -182,10 +164,11 @@ public final class Notification {
                 continue;
 
             Intent intent = new Intent(context, receiver)
-                    .setAction(PREF_KEY + "#" + request.getIdentifier())
+                    .setAction(PREF_KEY_ID + request.getIdentifier())
                     .putExtra(Notification.EXTRA_ID, options.getId())
                     .putExtra(Request.EXTRA_OCCURRENCE, request.getOccurrence());
 
+            ids.add(intent.getAction());
             intents.add(new Pair<Date, Intent>(date, intent));
         }
         while (request.moveNext());
@@ -193,6 +176,8 @@ public final class Notification {
         if (intents.isEmpty())
             return;
 
+        persist(ids);
+
         Intent last = intents.get(intents.size() - 1).second;
         last.putExtra(Request.EXTRA_LAST, true);
 
@@ -219,14 +204,11 @@ public final class Notification {
                         mgr.setExact(RTC_WAKEUP, time, pi);
                         break;
                 }
-                ids.add(intent.getAction());
             } catch (Exception ignore) {
                 // Samsung devices have a known bug where a 500 alarms limit
                 // can crash the app
             }
         }
-
-        persist(ids);
     }
 
     /**
@@ -253,7 +235,7 @@ public final class Notification {
     /**
      * Clear the local notification without canceling repeating alarms.
      */
-    public void clear () {
+    public void clear() {
         getNotMgr().cancel(getId());
 
         if (isRepeating())
@@ -271,8 +253,9 @@ public final class Notification {
      * method and cancel it.
      */
     public void cancel() {
-        Set<String> actions = getPrefs().getStringSet(
-                "#" + options.getIdentifier(), null);
+        SharedPreferences prefs = getPrefs(PREF_KEY_PID);
+        String id               = options.getIdentifier();
+        Set<String> actions     = prefs.getStringSet(id, null);
 
         unpersist();
         getNotMgr().cancel(options.getId());
@@ -295,7 +278,7 @@ public final class Notification {
     /**
      * Present the local notification to user.
      */
-    public void show () {
+    public void show() {
 
         if (builder == null)
             return;
@@ -304,22 +287,6 @@ public final class Notification {
         getNotMgr().notify(getId(), builder.build());
     }
 
-    // /**
-    //  * Count of triggers since schedule.
-    //  */
-    // public int getTriggerCountSinceSchedule() {
-    //     long now = System.currentTimeMillis();
-    //     long triggerTime = options.getTriggerTime();
-
-    //     if (!wasInThePast())
-    //         return 0;
-
-    //     if (!isRepeating())
-    //         return 1;
-
-    //     return (int) ((now - triggerTime) / options.getRepeatInterval());
-    // }
-
     /**
      * Encode options to JSON.
      */
@@ -344,11 +311,15 @@ public final class Notification {
      * @param ids List of intent actions to persist.
      */
     private void persist (Set<String> ids) {
-        SharedPreferences.Editor editor = getPrefs().edit();
         String id = options.getIdentifier();
+        SharedPreferences.Editor editor;
 
+        editor = getPrefs(PREF_KEY_ID).edit();
         editor.putString(id, options.toString());
-        editor.putStringSet("#" + id, ids);
+        editor.apply();
+
+        editor = getPrefs(PREF_KEY_PID).edit();
+        editor.putStringSet(id, ids);
         editor.apply();
     }
 
@@ -356,12 +327,15 @@ public final class Notification {
      * Remove the notification from the Android shared Preferences.
      */
     private void unpersist () {
-        SharedPreferences.Editor editor = getPrefs().edit();
-        String id = options.getIdentifier();
-
-        editor.remove(id);
-        editor.remove("#" + id);
-        editor.apply();
+        String[] keys = { PREF_KEY_ID, PREF_KEY_PID };
+        String id     = options.getIdentifier();
+        SharedPreferences.Editor editor;
+
+        for (String key : keys) {
+            editor = getPrefs(key).edit();
+            editor.remove(id);
+            editor.apply();
+        }
     }
 
     /**
@@ -383,8 +357,8 @@ public final class Notification {
     /**
      * Shared private preferences for the application.
      */
-    private SharedPreferences getPrefs () {
-        return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
+    private SharedPreferences getPrefs (String key) {
+        return context.getSharedPreferences(key, Context.MODE_PRIVATE);
     }
 
     /**

+ 1 - 1
src/android/notification/Options.java

@@ -106,7 +106,7 @@ public final class Options {
     /**
      * Wrapped JSON object.
      */
-    JSONObject getDict () {
+    public JSONObject getDict() {
         return options;
     }