Quellcode durchsuchen

Support for messaging styled notifications

Sebastián Katzer vor 8 Jahren
Ursprung
Commit
402e3a0948

+ 4 - 4
src/android/ClickActivity.java

@@ -41,11 +41,11 @@ public class ClickActivity extends de.appplant.cordova.plugin.notification.activ
 
         super.onClick(notification);
 
-        // if (notification.getOptions().isOngoing())
-        //     return;
+        if (notification.getOptions().isSticky())
+            return;
 
-        // String event = notification.isRepeating() ? "clear" : "cancel";
-        // LocalNotification.fireEvent(event, notification);
+        String event = notification.isRepeating() ? "clear" : "cancel";
+        LocalNotification.fireEvent(event, notification);
     }
 
 }

+ 91 - 25
src/android/notification/Builder.java

@@ -26,6 +26,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.NotificationCompat.MessagingStyle.Message;
 
 import java.util.List;
 import java.util.Random;
@@ -137,43 +138,108 @@ public final class Builder {
     /**
      * Find out and set the notification style.
      *
-     * @param builder Local notification builder instance
+     * @param builder Local notification builder instance.
      */
     private void applyStyle(NotificationCompat.Builder builder) {
+        Message[] messages = options.getMessages();
+        String summary     = options.getSummary();
+
+        if (messages != null) {
+            applyMessagingStyle(builder, messages);
+            return;
+        }
+
         List<Bitmap> pics = options.getAttachments();
-        String summary    = options.getSummary();
-        String text       = options.getText();
 
         if (pics.size() > 0) {
-            NotificationCompat.BigPictureStyle style =
-                    new NotificationCompat.BigPictureStyle(builder)
-                            .setSummaryText(summary == null ? text : summary)
-                            .bigPicture(pics.get(0));
-
-            builder.setStyle(style);
+            applyBigPictureStyle(builder, pics);
             return;
         }
 
-        if (text != null && text.contains("\n")) {
-            NotificationCompat.InboxStyle style =
-                    new NotificationCompat.InboxStyle(builder)
-                            .setSummaryText(summary);
-
-            for (String line : text.split("\n")) {
-                style.addLine(line);
-            }
+        String text = options.getText();
 
-            builder.setStyle(style);
+        if (text != null && text.contains("\n")) {
+            applyInboxStyle(builder);
             return;
         }
 
         if (text == null || summary == null && text.length() < 45)
             return;
 
-        NotificationCompat.BigTextStyle style =
-                new NotificationCompat.BigTextStyle(builder)
-                        .setSummaryText(summary)
-                        .bigText(text);
+        applyBigTextStyle(builder);
+    }
+
+    /**
+     * Apply inbox style.
+     *
+     * @param builder  Local notification builder instance.
+     * @param messages The messages to add to the conversation.
+     */
+    private void applyMessagingStyle(NotificationCompat.Builder builder,
+                                     Message[] messages) {
+
+        NotificationCompat.MessagingStyle style;
+
+        style = new NotificationCompat.MessagingStyle("Me")
+                .setConversationTitle(options.getTitle());
+
+        for (Message msg : messages) {
+            style.addMessage(msg);
+        }
+
+        builder.setStyle(style);
+    }
+
+    /**
+     * Apply inbox style.
+     *
+     * @param builder Local notification builder instance.
+     * @param pics    The pictures to show.
+     */
+    private void applyBigPictureStyle(NotificationCompat.Builder builder,
+                                      List<Bitmap> pics) {
+
+        NotificationCompat.BigPictureStyle style;
+        String summary = options.getSummary();
+        String text    = options.getText();
+
+        style = new NotificationCompat.BigPictureStyle(builder)
+                .setSummaryText(summary == null ? text : summary)
+                .bigPicture(pics.get(0));
+
+        builder.setStyle(style);
+    }
+
+    /**
+     * Apply inbox style.
+     *
+     * @param builder Local notification builder instance.
+     */
+    private void applyInboxStyle(NotificationCompat.Builder builder) {
+        NotificationCompat.InboxStyle style;
+        String text = options.getText();
+
+        style = new NotificationCompat.InboxStyle(builder)
+                .setSummaryText(options.getSummary());
+
+        for (String line : text.split("\n")) {
+            style.addLine(line);
+        }
+
+        builder.setStyle(style);
+    }
+
+    /**
+     * Apply big text style.
+     *
+     * @param builder Local notification builder instance.
+     */
+    private void applyBigTextStyle(NotificationCompat.Builder builder) {
+        NotificationCompat.BigTextStyle style;
+
+        style = new NotificationCompat.BigTextStyle(builder)
+                .setSummaryText(options.getSummary())
+                .bigText(options.getText());
 
         builder.setStyle(style);
     }
@@ -182,7 +248,7 @@ public final class Builder {
      * Set intent to handle the delete event. Will clean up some persisted
      * preferences.
      *
-     * @param builder Local notification builder instance
+     * @param builder Local notification builder instance.
      */
     private void applyDeleteReceiver(NotificationCompat.Builder builder) {
 
@@ -203,7 +269,7 @@ public final class Builder {
      * Set intent to handle the click event. Will bring the app to
      * foreground.
      *
-     * @param builder Local notification builder instance
+     * @param builder Local notification builder instance.
      */
     private void applyContentReceiver(NotificationCompat.Builder builder) {
 
@@ -225,7 +291,7 @@ public final class Builder {
     /**
      * Add all actions to the builder if there are any actions.
      *
-     * @param builder Local notification builder instance
+     * @param builder Local notification builder instance.
      */
     private void applyActions (NotificationCompat.Builder builder) {
         Action[] actions = options.getActions();

+ 61 - 107
src/android/notification/Notification.java

@@ -108,19 +108,12 @@ public final class Notification {
         return options.getId();
     }
 
-    // /**
-    //  * If it's a repeating notification.
-    //  */
-    // public boolean isRepeating () {
-    //     return getOptions().getRepeatInterval() > 0;
-    // }
-
-    // /**
-    //  * If the notification was in the past.
-    //  */
-    // public boolean wasInThePast () {
-    //     return new Date().after(options.getTriggerDate());
-    // }
+    /**
+     * If it's a repeating notification.
+     */
+    public boolean isRepeating () {
+        return getOptions().getTrigger().has("every");
+    }
 
     // /**
     //  * If the notification is scheduled.
@@ -160,61 +153,37 @@ public final class Notification {
     // }
 
     /**
-     * Schedule the local notification.
+     * Clear the local notification without canceling repeating alarms.
      */
-    public void schedule() {
-        // long triggerTime = options.getTriggerTime();
+    public void clear () {
 
-        // persist();
+        // if (!isRepeating() && wasInThePast())
+        //     unpersist();
 
-        // // Intent gets called when the Notification gets fired
-        // Intent intent = new Intent(context, receiver)
-        //         .setAction(options.getIdStr())
-        //         .putExtra(Options.EXTRA, options.toString());
-
-        // PendingIntent pi = PendingIntent.getBroadcast(
-        //         context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-
-        // if (isRepeating()) {
-        //     getAlarmMgr().setRepeating(AlarmManager.RTC_WAKEUP,
-        //             triggerTime, options.getRepeatInterval(), pi);
-        // } else {
-        //     getAlarmMgr().set(AlarmManager.RTC_WAKEUP, triggerTime, pi);
-        // }
+        // if (!isRepeating())
+        //     getNotMgr().cancel(getId());
     }
 
-    // /**
-    //  * Clear the local notification without canceling repeating alarms.
-    //  */
-    // public void clear () {
-
-    //     if (!isRepeating() && wasInThePast())
-    //         unpersist();
-
-    //     if (!isRepeating())
-    //         getNotMgr().cancel(getId());
-    // }
-
-    // /**
-    //  * Cancel the local notification.
-    //  *
-    //  * Create an intent that looks similar, to the one that was registered
-    //  * using schedule. Making sure the notification id in the action is the
-    //  * same. Now we can search for such an intent using the 'getService'
-    //  * method and cancel it.
-    //  */
-    // public void cancel() {
-    //     Intent intent = new Intent(context, receiver)
-    //             .setAction(options.getIdStr());
+    /**
+     * Cancel the local notification.
+     *
+     * Create an intent that looks similar, to the one that was registered
+     * using schedule. Making sure the notification id in the action is the
+     * same. Now we can search for such an intent using the 'getService'
+     * method and cancel it.
+     */
+    public void cancel() {
+        // Intent intent = new Intent(context, receiver)
+        //         .setAction(options.getIdStr());
 
-    //     PendingIntent pi = PendingIntent.
-    //             getBroadcast(context, 0, intent, 0);
+        // PendingIntent pi = PendingIntent.
+        //         getBroadcast(context, 0, intent, 0);
 
-    //     getAlarmMgr().cancel(pi);
-    //     getNotMgr().cancel(options.getId());
+        // getAlarmMgr().cancel(pi);
+        // getNotMgr().cancel(options.getId());
 
-    //     unpersist();
-    // }
+        // unpersist();
+    }
 
     /**
      * Present the local notification to user.
@@ -249,58 +218,43 @@ public final class Notification {
     //     return (int) ((now - triggerTime) / options.getRepeatInterval());
     // }
 
-    // /**
-    //  * Encode options to JSON.
-    //  */
-    // public String toString() {
-    //     JSONObject dict = options.getDict();
-    //     JSONObject json = new JSONObject();
-
-    //     try {
-    //         json = new JSONObject(dict.toString());
-    //     } catch (JSONException e) {
-    //         e.printStackTrace();
-    //     }
-
-    //     json.remove("firstAt");
-    //     json.remove("updated");
-    //     json.remove("soundUri");
-    //     json.remove("iconUri");
-
-    //     return json.toString();
-    // }
-
-    // /**
-    //  * Persist the information of this notification to the Android Shared
-    //  * Preferences. This will allow the application to restore the notification
-    //  * upon device reboot, app restart, retrieve notifications, aso.
-    //  */
-    // private void persist () {
-    //     SharedPreferences.Editor editor = getPrefs().edit();
+    /**
+     * Encode options to JSON.
+     */
+    public String toString() {
+        JSONObject dict = options.getDict();
+        JSONObject json = new JSONObject();
+
+        try {
+            json = new JSONObject(dict.toString());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
 
-    //     editor.putString(options.getIdStr(), options.toString());
+        return json.toString();
+    }
 
-    //     if (Build.VERSION.SDK_INT < 9) {
-    //         editor.commit();
-    //     } else {
-    //         editor.apply();
-    //     }
-    // }
+    /**
+     * Persist the information of this notification to the Android Shared
+     * Preferences. This will allow the application to restore the notification
+     * upon device reboot, app restart, retrieve notifications, aso.
+     */
+    private void persist () {
+        SharedPreferences.Editor editor = getPrefs().edit();
 
-    // /**
-    //  * Remove the notification from the Android shared Preferences.
-    //  */
-    // private void unpersist () {
-    //     SharedPreferences.Editor editor = getPrefs().edit();
+        editor.putString(options.getIdentifier(), options.toString());
+        editor.apply();
+    }
 
-    //     editor.remove(options.getIdStr());
+    /**
+     * Remove the notification from the Android shared Preferences.
+     */
+    private void unpersist () {
+        SharedPreferences.Editor editor = getPrefs().edit();
 
-    //     if (Build.VERSION.SDK_INT < 9) {
-    //         editor.commit();
-    //     } else {
-    //         editor.apply();
-    //     }
-    // }
+        editor.remove(options.getIdentifier());
+        editor.apply();
+    }
 
     /**
      * Shared private preferences for the application.

+ 66 - 32
src/android/notification/Options.java

@@ -26,12 +26,14 @@ import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.net.Uri;
 import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.NotificationCompat.MessagingStyle.Message;
 
 import org.json.JSONArray;
 import org.json.JSONObject;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 import de.appplant.cordova.plugin.notification.util.AssetUtil;
@@ -121,13 +123,6 @@ public final class Options {
         return getId().toString();
     }
 
-    /**
-     * Text for the local notification.
-     */
-    public String getText() {
-        return options.optString("text", "");
-    }
-
     /**
      * Badge number for the local notification.
      */
@@ -138,7 +133,7 @@ public final class Options {
     /**
      * ongoing flag for local notifications.
      */
-    Boolean isSticky() {
+    public Boolean isSticky() {
         return options.optBoolean("sticky", false);
     }
 
@@ -149,6 +144,42 @@ public final class Options {
         return options.optBoolean("autoClear", false);
     }
 
+    /**
+     * Gets the raw trigger spec as provided by the user.
+     */
+    public JSONObject getTrigger() {
+        return options.optJSONObject("trigger");
+    }
+
+    /**
+     * Gets the value of the silent flag.
+     */
+    boolean isSilent() {
+        return options.optBoolean("silent", false);
+    }
+
+    /**
+     * The group for that notification.
+     */
+    String getGroup() {
+        return options.optString("group", null);
+    }
+
+    /**
+     * If the group shall show a summary.
+     */
+    boolean getGroupSummary() {
+        return options.optBoolean("groupSummary", false);
+    }
+
+    /**
+     * Text for the local notification.
+     */
+    public String getText() {
+        Object text = options.opt("text");
+        return text instanceof String ? (String) text : "";
+    }
+
     /**
      * Title for the local notification.
      */
@@ -497,27 +528,6 @@ public final class Options {
         return pics;
     }
 
-    /**
-     * The group for that notification.
-     */
-    String getGroup() {
-        return options.optString("group", null);
-    }
-
-    /**
-     * If the group shall show a summary.
-     */
-    boolean getGroupSummary() {
-        return options.optBoolean("groupSummary", false);
-    }
-
-    /**
-     * Gets the value of the silent flag.
-     */
-    boolean isSilent() {
-        return options.optBoolean("silent", false);
-    }
-
     /**
      * Gets the list of actions to display.
      */
@@ -543,10 +553,34 @@ public final class Options {
     }
 
     /**
-     * Gets the raw trigger spec as provided by the user.
+     * Gets the list of messages to display.
+     *
+     * @return null if there are no messages.
      */
-    public JSONObject getTrigger() {
-        return options.optJSONObject("trigger");
+    Message[] getMessages() {
+        Object value = options.opt("text");
+
+        if (value == null || value instanceof String)
+            return null;
+
+        JSONArray list = (JSONArray) value;
+
+        if (list.length() == 0)
+            return null;
+
+        Message[] messages = new Message[list.length()];
+        long now           = new Date().getTime();
+
+        for (int i = 0; i < messages.length; i++) {
+            JSONObject msg = list.optJSONObject(i);
+            String text    = msg.optString("text");
+            long timestamp = msg.optLong("date", now);
+            String person  = msg.optString("person", null);
+
+            messages[i] = new Message(text, timestamp, person);
+        }
+
+        return messages;
     }
 
     /**

+ 5 - 5
src/android/notification/activity/ClickActivity.java

@@ -40,11 +40,11 @@ public class ClickActivity extends AbstractClickActivity {
     public void onClick(Notification notification) {
         launchApp();
 
-        // if (notification.isRepeating()) {
-        //     notification.clear();
-        // } else {
-        //     notification.cancel();
-        // }
+        if (notification.isRepeating()) {
+            notification.clear();
+        } else {
+            notification.cancel();
+        }
     }
 
 }

+ 1 - 1
src/android/notification/receiver/ClearReceiver.java

@@ -37,7 +37,7 @@ public class ClearReceiver extends AbstractClearReceiver {
      */
     @Override
     public void onClear (Notification notification) {
-        // notification.clear();
+        notification.clear();
     }
 
 }

+ 0 - 4
www/local-notification-util.js

@@ -141,10 +141,6 @@ exports.convertProperties = function (options) {
         options.title = options.title.toString();
     }
 
-    if (options.text) {
-        options.text  = options.text.toString();
-    }
-
     if (options.badge) {
         options.badge = parseToInt('badge', options);
     }