Bläddra i källkod

Added new callback registration interface and new callback types

Sebastián Katzer 12 år sedan
förälder
incheckning
92ae360d34

+ 22 - 20
README.md

@@ -48,6 +48,7 @@ More informations can be found [here](https://build.phonegap.com/plugins/356).
 ## Release Notes
 #### Version 0.7.0 (not yet released)
 - **Note:** The new way of callback registration will be not compatible with previous versions! See #62
+- [feature:] Added new callback registration interface and new callback types.
 
 #### Version 0.7.0beta1 (17.01.2014)
 - [bugfix:] App throws an error on iOS if `message` is null.
@@ -123,8 +124,6 @@ window.plugin.notification.local.add({
     json:       String,  // Data to be passed through the notification
     autoCancel: Boolean, // Setting this flag and the notification is automatically canceled when the user clicks it
     ongoing:    Boolean, // Prevent clearing of notification (Android only)
-    foreground: String,  // A javascript function to be called if the app is running
-    background: String,  // A javascript function to be called if the app is in the background
 });
 ```
 **Note:** On Android the notification id needs to be a string which can be converted to a number. If the ID has an invalid format, it will be ignored, but canceling the notification will fail.
@@ -141,6 +140,15 @@ The method cancels all notifications which were previously added by the applicat
 window.plugin.notification.local.cancelAll();
 ```
 
+### onadd() | ontrigger() | onclick() | oncancel()
+There are 4 different callback types available. For each of them one listener can be specified. The listener has to be a function and takes the following arguments:
+ - event: The Name of the event
+ - id: The ID of the notification
+ - json:  A custom (JSON) string
+```javascript
+window.plugin.notification.local.on_callback_ = function (id, state, json) {};
+```
+
 
 ## Examples
 #### Will fire every week on this day, 60 seconds from now
@@ -149,22 +157,12 @@ var now                  = new Date().getTime(),
     _60_seconds_from_now = new Date(now + 60*1000);
 
 window.plugin.notification.local.add({
-    id:         1, // is converted to a string
-    title:      'Reminder',
-    message:    'Dont forget to buy some flowers.',
-    repeat:     'weekly',
-    date:       _60_seconds_from_now,
-    foreground: 'foreground',
-    background: 'background'
+    id:      1, // is converted to a string
+    title:   'Reminder',
+    message: 'Dont forget to buy some flowers.',
+    repeat:  'weekly',
+    date:    _60_seconds_from_now
 });
-
-function foreground (id) {
-    console.log('I WAS RUNNING ID='+id)
-}
-
-function background (id) {
-    console.log('I WAS IN THE BACKGROUND ID='+id)
-}
 ```
 
 #### Pop's up immediately
@@ -177,16 +175,20 @@ window.plugin.notification.local.add({ message: 'Great app!' });
 window.plugin.notification.local.add({ sound: null });
 ```
 
+#### Callback registration
+```javascript
+window.plugin.notification.local.onadd = function (id, state, json) {};
+```
+
 #### Pass data through the notification
 ```javascript
 window.plugin.notification.local.add({
     id:         1,
     message:    'I love BlackBerry!',
-    json:       { test: 123 },
-    foreground: 'foreground'
+    json:       { test: 123 }
 });
 
-function foreground (id, json) {
+window.plugin.notification.local.onclick = function (id, state, json) {
     console.log(id, JSON.parse(json).test);
 }
 ```

+ 1 - 1
plugin.xml

@@ -3,7 +3,7 @@
 <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
         xmlns:android="http://schemas.android.com/apk/res/android"
         id="de.appplant.cordova.plugin.local-notification"
-        version="0.7.0beta1">
+        version="0.7.0dev">
 
     <name>LocalNotification</name>
 

+ 37 - 5
src/android/LocalNotification.java

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file
@@ -33,6 +33,7 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -51,10 +52,10 @@ public class LocalNotification extends CordovaPlugin {
 
     protected final static String PLUGIN_NAME      = "LocalNotification";
 
-    protected static CordovaWebView webView        = null;
+    private   static CordovaWebView webView        = null;
     protected static Context context               = null;
 
-    protected static ArrayList<String> callbackQueue = new ArrayList<String>();
+    private   static ArrayList<String> callbackQueue = new ArrayList<String>();
 
     @Override
     public void initialize (CordovaInterface cordova, CordovaWebView webView) {
@@ -119,6 +120,8 @@ public class LocalNotification extends CordovaPlugin {
         AlarmManager am  = getAlarmManager();
         PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
 
+        fireEvent("add", options.getId(), options.getJSON());
+
         am.set(AlarmManager.RTC_WAKEUP, triggerTime, pi);
     }
 
@@ -136,7 +139,6 @@ public class LocalNotification extends CordovaPlugin {
          * Now we can search for such an intent using the 'getService' method
          * and cancel it.
          */
-
         Intent intent = new Intent(context, Receiver.class)
             .setAction("" + notificationId);
 
@@ -149,6 +151,8 @@ public class LocalNotification extends CordovaPlugin {
         try {
             nc.cancel(Integer.parseInt(notificationId));
         } catch (Exception e) {}
+
+        fireEvent("cancel", notificationId, "");
     }
 
     /**
@@ -210,12 +214,33 @@ public class LocalNotification extends CordovaPlugin {
      * Clear all alarms from the Android shared Preferences.
      */
     public static void unpersistAll () {
-        Editor editor = LocalNotification.getSharedPreferences().edit();
+        Editor editor = getSharedPreferences().edit();
 
         editor.clear();
         editor.commit();
     }
 
+    /**
+     * Fires the given event.
+     *
+     * @param {String} event The Name of the event
+     * @param {String} id    The ID of the notification
+     * @param {String} json  A custom (JSON) string
+     */
+    public static void fireEvent (String event, String id, String json) {
+        String state  = isInBackground() ? "background" : "foreground";
+        String params = "\"" + id + "\",\"" + state + "\",\\'" + JSONObject.quote(json) + "\\'.replace(/(^\"|\"$)/g, \\'\\')";
+        String js     = "setTimeout('plugin.notification.local.on" + event + "(" + params + ")',0)";
+
+        // after reboot, LocalNotification.webView is always be null
+        // call background callback later
+        if (webView == null) {
+            callbackQueue.add(js);
+        } else {
+            webView.sendJavascript(js);
+        }
+    }
+
     /**
      * Set the application context if not already set.
      */
@@ -246,6 +271,13 @@ public class LocalNotification extends CordovaPlugin {
         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
     }
 
+    /**
+     * Gibt an, ob die App im Hintergrund läuft.
+     */
+    private static boolean isInBackground () {
+        return !context.getPackageName().equalsIgnoreCase(((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningTasks(1).get(0).topActivity.getPackageName());
+    }
+
     /**
      * Calls all pending callbacks after the webview was created.
      */

+ 1 - 19
src/android/Options.java

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file
@@ -186,20 +186,6 @@ public class Options {
         return options.optInt("smallIcon", resId);
     }
 
-    /**
-     * Gibt den Pfad zur Callback-Funktion der Notification an.
-     */
-    public String getForeground () {
-        return options.optString("foreground", null);
-    }
-
-    /**
-     * Gibt den Pfad zur Callback-Funktion der Notification an.
-     */
-    public String getBackground () {
-        return options.optString("background", null);
-    }
-
     /**
      * Gibt das Intervall an, in dem die Notification aufpoppen soll (daily, weekly, monthly, yearly)
      */
@@ -228,10 +214,6 @@ public class Options {
         return options.optBoolean("autoCancel", false);
     }
 
-    public Boolean getOngoing() {
-        return options.optBoolean("ongoing", false);
-    }
-
     /**
      * Gibt die zusätzlichen Daten als String an.
      */

+ 8 - 29
src/android/Receiver.java

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file
@@ -28,7 +28,6 @@ import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.annotation.SuppressLint;
-import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.app.NotificationManager;
@@ -40,7 +39,6 @@ import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Build;
 import android.os.Bundle;
-import android.text.TextUtils;
 
 /**
  * The alarm receiver is triggered when a scheduled alarm is fired. This class
@@ -74,6 +72,8 @@ public class Receiver extends BroadcastReceiver {
         // The context may got lost if the app was not running before
         LocalNotification.setContext(context);
 
+        fireTriggerEvent();
+
         if (options.getInterval() == 0) {
             LocalNotification.unpersist(options.getId());
         } else if (isFirstAlarmInFuture()) {
@@ -84,10 +84,6 @@ public class Receiver extends BroadcastReceiver {
 
         Builder notification = buildNotification();
 
-        if (!isInBackground(context)) {
-            invokeForegroundCallback();
-        }
-
         showNotification(notification);
     }
 
@@ -130,8 +126,7 @@ public class Receiver extends BroadcastReceiver {
         .setSmallIcon(options.getSmallIcon())
         .setLargeIcon(icon)
         .setSound(options.getSound())
-        .setAutoCancel(options.getAutoCancel())
-        .setOngoing(options.getOngoing());
+        .setAutoCancel(options.getAutoCancel());
 
         setClickEvent(notification);
 
@@ -176,25 +171,9 @@ public class Receiver extends BroadcastReceiver {
     }
 
     /**
-     * Gibt an, ob die App im Hintergrund läuft.
-     */
-    private boolean isInBackground (Context context) {
-        return !context.getPackageName().equalsIgnoreCase(((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningTasks(1).get(0).topActivity.getPackageName());
-    }
-
-    /**
-     * Ruft die `foreground` Callback Funktion auf.
+     * Fires ontrigger event.
      */
-    private void invokeForegroundCallback () {
-        String function = options.getForeground();
-
-        // after reboot, LocalNotification.webView is always null
-        // may be call foreground callback later
-        if (!TextUtils.isEmpty(function) && LocalNotification.webView != null) {
-            String params = "\"" + options.getId() + "\",\\'" + JSONObject.quote(options.getJSON()) + "\\'.replace(/(^\"|\"$)/g, \\'\\')";
-            String js     = "setTimeout('" + function + "(" + params + ")',0)";
-
-            LocalNotification.webView.sendJavascript(js);
-        }
+    private void fireTriggerEvent () {
+        LocalNotification.fireEvent("trigger", options.getId(), options.getJSON());
     }
-}
+}

+ 5 - 20
src/android/ReceiverActivity.java

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file
@@ -28,7 +28,6 @@ import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
-import android.text.TextUtils;
 
 public class ReceiverActivity extends Activity {
 
@@ -45,7 +44,7 @@ public class ReceiverActivity extends Activity {
             Options options = new Options(getApplicationContext()).parse(args);
 
             launchMainIntent();
-            invokeBackgroundCallback(options);
+            fireClickEvent(options);
         } catch (JSONException e) {}
     }
 
@@ -63,23 +62,9 @@ public class ReceiverActivity extends Activity {
     }
 
     /**
-     * Ruft die `background` Callback Funktion auf.
+     * Fires the onclick event.
      */
-    private void invokeBackgroundCallback (Options options) {
-        String function = options.getBackground();
-
-        if (TextUtils.isEmpty(function))
-            return;
-
-        String params   = "\"" + options.getId() + "\",\\'" + JSONObject.quote(options.getJSON()) + "\\'.replace(/(^\"|\"$)/g, \\'\\')";
-        final String js = "setTimeout('" + function + "(" + params + ")',0)";
-
-        // after reboot, LocalNotification.webView is always null
-        // call background callback later
-        if (LocalNotification.webView == null) {
-            LocalNotification.callbackQueue.add(js);
-        } else {
-            LocalNotification.webView.sendJavascript(js);
-        }
+    private void fireClickEvent (Options options) {
+        LocalNotification.fireEvent("click", options.getId(), options.getJSON());
     }
 }

+ 1 - 1
src/android/Restore.java

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file

+ 1 - 1
src/ios/APPLocalNotification.h

@@ -1,5 +1,5 @@
 /*
- Copyright 2013 appPlant UG
+ Copyright 2013-2014 appPlant UG
 
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file

+ 39 - 23
src/ios/APPLocalNotification.m

@@ -1,5 +1,5 @@
 /*
- Copyright 2013 appPlant UG
+ Copyright 2013-2014 appPlant UG
 
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
@@ -54,11 +54,14 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
         NSArray* arguments                = [command arguments];
         NSMutableDictionary* options      = [arguments objectAtIndex:0];
         UILocalNotification* notification = [self notificationWithProperties:options];
-        NSString* notificationId          = [notification.userInfo objectForKey:@"id"];
+        NSString* id                      = [notification.userInfo objectForKey:@"id"];
+        NSString* json                    = [notification.userInfo objectForKey:@"json"];
 
-        [self cancelNotificationWithId:notificationId];
+        [self cancelNotificationWithId:id];
         [self archiveNotification:notification];
 
+        [self fireEvent:@"add" id:id json:json];
+
         [[UIApplication sharedApplication] scheduleLocalNotification:notification];
     }];
 }
@@ -71,10 +74,13 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
 - (void) cancel:(CDVInvokedUrlCommand*)command
 {
     [self.commandDelegate runInBackground:^{
-        NSArray* arguments       = [command arguments];
-        NSString* notificationId = [arguments objectAtIndex:0];
+        NSArray* arguments = [command arguments];
+        NSString* id       = [arguments objectAtIndex:0];
 
-        [self cancelNotificationWithId:notificationId];
+        UILocalNotification* notification = [self cancelNotificationWithId:id];
+        NSString* json                    = [notification.userInfo objectForKey:@"json"];
+
+        [self fireEvent:@"cancel" id:id json:json];
     }];
 }
 
@@ -105,7 +111,7 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
  *
  * @param {NSString} id Die ID der Notification
  */
-- (void) cancelNotificationWithId:(NSString*)id
+- (UILocalNotification*) cancelNotificationWithId:(NSString*)id
 {
     if (![self strIsNullOrEmpty:id])
     {
@@ -118,8 +124,12 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
 
             [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
             [[UIApplication sharedApplication] cancelLocalNotification:notification];
+
+            return notification;
         }
     }
+
+    return NULL;
 }
 
 /**
@@ -163,17 +173,11 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
 - (NSDictionary*) userDict:(NSMutableDictionary*)options
 {
     NSString* id = [options objectForKey:@"id"];
-    NSString* bg = [options objectForKey:@"background"];
-    NSString* fg = [options objectForKey:@"foreground"];
     NSString* ac = [options objectForKey:@"autoCancel"];
     NSString* js = [options objectForKey:@"json"];
 
     return [NSDictionary dictionaryWithObjectsAndKeys:
-            id, @"id",
-            bg, @"background",
-            fg, @"foreground",
-            ac, @"autoCancel",
-            js, @"json", nil];
+            id, @"id", ac, @"autoCancel", js, @"json", nil];
 }
 
 /**
@@ -231,12 +235,11 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
 {
     UIApplicationState state          = [[UIApplication sharedApplication] applicationState];
     bool isActive                     = state == UIApplicationStateActive;
+    NSString* event                   = isActive ? @"trigger" : @"click";
 
     UILocalNotification* notification = [localNotification object];
     NSString* id                      = [notification.userInfo objectForKey:@"id"];
     NSString* json                    = [notification.userInfo objectForKey:@"json"];
-    NSString* callbackType            = isActive ? @"foreground" : @"background";
-    NSString* callbackFn              = [notification.userInfo objectForKey:callbackType];
     BOOL autoCancel                   = [[notification.userInfo objectForKey:@"autoCancel"] boolValue];
 
     if (autoCancel && !isActive)
@@ -244,13 +247,7 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
         [self cancelNotificationWithId:id];
     }
 
-    if (![self strIsNullOrEmpty:callbackFn])
-    {
-        NSString* params = [NSString stringWithFormat:@"\"%@\",\\'%@\\'", id, json];
-        NSString* js     = [NSString stringWithFormat:@"setTimeout('%@(%@)',0)", callbackFn, params];
-
-        [self.commandDelegate evalJs:js];
-    }
+    [self fireEvent:event id:id json:json];
 }
 
 /**
@@ -269,4 +266,23 @@ NSString *const kAPP_LOCALNOTIFICATION = @"APP_LOCALNOTIFICATION";
     return (str == (NSString*)[NSNull null] || [str isEqualToString:@""]) ? YES : NO;
 }
 
+/**
+ * Fires the given event.
+ *
+ * @param {String} event The Name of the event
+ * @param {String} id    The ID of the notification
+ * @param {String} json  A custom (JSON) string
+ */
+- (void) fireEvent:(NSString*) event id:(NSString*) id json:(NSString*) json
+{
+    UIApplicationState state = [[UIApplication sharedApplication] applicationState];
+    bool isActive            = state == UIApplicationStateActive;
+    NSString* stateName      = isActive ? @"foreground" : @"background";
+
+    NSString* params = [NSString stringWithFormat:@"\"%@\",\"%@\",\\'%@\\'", id, stateName, json];
+    NSString* js     = [NSString stringWithFormat:@"setTimeout('plugin.notification.local.on%@(%@)',0)", event, params];
+
+    [self.commandDelegate evalJs:js];
+}
+
 @end

+ 1 - 1
src/wp8/LocalNotification.cs

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file

+ 1 - 13
src/wp8/Options.cs

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file
@@ -86,18 +86,6 @@ namespace De.APPPlant.Cordova.Plugin.LocalNotification
         [DataMember(IsRequired = false, Name = "id")]
         public string ID { get; set; }
 
-        /// <summary>
-        /// A javascript function to be called if the app is in the background
-        /// </summary>
-        [DataMember(IsRequired = false, Name = "background")]
-        public string Background { get; set; }
-
-        /// <summary>
-        /// A javascript function to be called if the app is running
-        /// </summary>
-        [DataMember(IsRequired = false, Name = "foreground")]
-        public string Foreground { get; set; }
-
         /// <summary>
         /// Setting this flag will make it so the notification is automatically canceled when the user clicks it
         /// </summary>

+ 40 - 10
www/local-notification.js

@@ -1,5 +1,5 @@
 /*
-    Copyright 2013 appPlant UG
+    Copyright 2013-2014 appPlant UG
 
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file
@@ -40,9 +40,7 @@ LocalNotification.prototype = {
             badge:      0,
             id:         '0',
             json:       '',
-            repeat:     '',
-            background: '',
-            foreground: ''
+            repeat:     ''
         };
 
         switch (device.platform) {
@@ -58,10 +56,6 @@ LocalNotification.prototype = {
                 defaults.wideImage = null;
         };
 
-        var callbackFn = function (cmd) {
-            eval(cmd);
-        };
-
         for (var key in defaults) {
             if (options[key] !== undefined) {
                 defaults[key] = options[key];
@@ -76,7 +70,7 @@ LocalNotification.prototype = {
             defaults.date = Math.round(defaults.date.getTime()/1000);
         }
 
-        cordova.exec(callbackFn, null, 'LocalNotification', 'add', [defaults]);
+        cordova.exec(null, null, 'LocalNotification', 'add', [defaults]);
 
         return defaults.id;
     },
@@ -95,7 +89,43 @@ LocalNotification.prototype = {
      */
     cancelAll: function () {
         cordova.exec(null, null, 'LocalNotification', 'cancelAll', []);
-    }
+    },
+
+    /**
+     * Occurs when a notification was added.
+     *
+     * @param {String} id    The ID of the notification
+     * @param {String} state Either "foreground" or "background"
+     * @param {String} json  A custom (JSON) string
+     */
+    onadd: function (id, state, json) {},
+
+    /**
+     * Occurs when the notification is triggered.
+     *
+     * @param {String} id    The ID of the notification
+     * @param {String} state Either "foreground" or "background"
+     * @param {String} json  A custom (JSON) string
+     */
+    ontrigger: function (id, state, json) {},
+
+    /**
+     * Fires after the notification was clicked.
+     *
+     * @param {String} id    The ID of the notification
+     * @param {String} state Either "foreground" or "background"
+     * @param {String} json  A custom (JSON) string
+     */
+    onclick: function (id, state, json) {},
+
+    /**
+     * Fires if the notification was canceled.
+     *
+     * @param {String} id    The ID of the notification
+     * @param {String} state Either "foreground" or "background"
+     * @param {String} json  A custom (JSON) string
+     */
+    oncancel: function (id, state, json) {}
 };
 
 var plugin = new LocalNotification();