From 6529a9df540a0baf755198dd9d219e237ccc8418 Mon Sep 17 00:00:00 2001 From: Jeroen van Vianen Date: Tue, 8 Sep 2015 22:59:37 +0200 Subject: [PATCH] New version with additional properties to specified in either the notification settings or in the notification payload sent from the server: - priority: -2 to +2 to specify the notification priority - insistent: true/false whether the notification should be insistent - group: the name of the group to group similar notifications together - localOnly: whether the notification should be bridged to other devices or is only relevant to the current device --- LICENSE | 2 +- README.md | 24 +++-- example/app.js | 14 ++- manifest | 2 +- .../android/gcm/GCMIntentService.java | 93 +++++++++++++++++-- src/nl/vanvianen/android/gcm/GCMModule.java | 8 -- timodule.xml | 7 +- 7 files changed, 112 insertions(+), 38 deletions(-) diff --git a/LICENSE b/LICENSE index 8f71f43..7b3b6a0 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright 2015 Jeroen van Vianen Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index b393e30..c442c4c 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,30 @@ # Titanium Module for Google Cloud Messaging Push Notifications for Android # -A Titanium module for registering a device with GCM and handling push notifications sent to the device. +A Titanium module for registering a device with Google Cloud Messaging and handling push notifications sent to the device. + +1. Install the module as usual in Titanium Studio by downloading the [zip file](https://github.com/morinel/gcmpush/releases/download/1.0/nl.vanvianen.android.gcm-android-1.0.zip) or use + +``` +gittio install nl.vanvianen.android.gcm +``` -1. Install the module as usual in Titanium Studio by downloading the [zip file](https://github.com/morinel/gcmpush/releases/download/1.0/nl.vanvianen.android.gcm-android-1.0.zip) 1. Refer to the example for possibilities 1. Send a server push notification with your preferred server-side technology to the registrationId returned while registering your device. 1. The callback you specified will then be called This module does not require any tiapp.xml properties, all configuration is done in Javascript. -There are four notification settings that can be specified: +There are five notification settings that can be specified: -1. sound: the sound file to play while receiving the notification or 'default' for the default sound. The sound file should be placed in platform/android/res/raw directory. -1. smallIcon: the tiny icon shown at the top of the screen, see this [stackoverflow question](http://stackoverflow.com/questions/28387602/notification-bar-icon-turns-white-in-android-5-lollipop) for details. The file should be placed in platform/android/res/drawable -1. largeIcon: the large icon shown in the notification bar. If not specified your appicon will be used. The file should be placed in platform/android/res/drawable. -1. vibrate (true / false): whether vibration should be on +1. smallIcon: the tiny icon shown at the top of the screen, see this [stackoverflow question](http://stackoverflow.com/questions/28387602/notification-bar-icon-turns-white-in-android-5-lollipop) for details. The file should be placed in ```platform/android/res/drawable```. +1. largeIcon: the large icon shown in the notification bar. If not specified your appicon will be used. The file should be placed in ```platform/android/res/drawable```. +1. sound: the sound file to play while receiving the notification or 'default' for the default sound. The sound file should be placed in the ```platform/android/res/raw``` directory. +1. vibrate (true / false): whether vibration should be on, default false. +1. insistent (true / false): whether the notification should be [insistent](http://developer.android.com/reference/android/app/Notification.html#FLAG_INSISTENT), default false. +1. group: name of group to group similar notifications together, default null. +1. localOnly: whether this notification should be bridged to other devices (false) or is only relevant to this device (true), default true. +1. priority: specifies the priority of the notification, should be between [PRIORITY_MIN](http://developer.android.com/reference/android/support/v4/app/NotificationCompat.html#PRIORITY_MIN) and [PRIORITY_MAX](http://developer.android.com/reference/android/support/v4/app/NotificationCompat.html#PRIORITY_MAX) +The settings sound, vibrate, and insistent can also be set as data in the push message being received. If the app is not active when the notification is received, use gcm.getLastData() to retrieve the contents of the notification and act accordingly to start or resume the app in a suitable way. If you're done, call gcm.clearLastData(), otherwise the same logic will happen when resuming the app again. \ No newline at end of file diff --git a/example/app.js b/example/app.js index 0a4fa5a..c2dd366 100644 --- a/example/app.js +++ b/example/app.js @@ -12,17 +12,21 @@ gcm.registerPush({ /* It's the same as your project id */ senderId: 'XXXXXXXX', notificationSettings: { - sound: 'mysound.mp3', /* Place in platform/android/res/raw/mysound.mp3 */ - smallIcon: 'notification_icon.png', /* Place in platform/android/res/drawable/notification_icon.png */ + sound: 'mysound.mp3', /* Place soudn file in platform/android/res/raw/mysound.mp3 */ + smallIcon: 'notification_icon.png', /* Place icon in platform/android/res/drawable/notification_icon.png */ largeIcon: 'appicon.png', /* Same */ - vibrate: true + vibrate: true, /* Whether the phone should vibrate */ + insistent: true, /* Whether the notification should be insistent */ + group: 'MyNotificationGroup', /* Name of group to group similar notifications together */ + localOnly: false, /* Whether this notification should be bridged to other devices */ + priority: +2 /* Notification priority, from -2 to +2 */ }, success: function (event) { Ti.API.info("Push registration success: " + JSON.stringify(event)); /* Add code to send event.registrationId to your server */ }, error: function (event) { - Ti.API.info("Push registration error = " + JSON.stringify(event)); + Ti.API.info("Push registration error: " + JSON.stringify(event)); alert(event.error); }, callback: function (event) { @@ -31,7 +35,7 @@ gcm.registerPush({ var dialog = Ti.UI.createAlertDialog({ title: 'Push received', - message: JSON.stringify(event.data) + message: JSON.stringify(event.data), buttonNames: ['View'], cancel: 1 }); diff --git a/manifest b/manifest index ae4d35a..95c07df 100644 --- a/manifest +++ b/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 1.0 +version: 1.1 apiversion: 2 description: Google Cloud Push for Titanium author: Jeroen van Vianen diff --git a/src/nl/vanvianen/android/gcm/GCMIntentService.java b/src/nl/vanvianen/android/gcm/GCMIntentService.java index bad7437..27bfb44 100644 --- a/src/nl/vanvianen/android/gcm/GCMIntentService.java +++ b/src/nl/vanvianen/android/gcm/GCMIntentService.java @@ -84,7 +84,11 @@ protected void onMessage(Context context, Intent intent) { int smallIcon = 0; int largeIcon = 0; String sound = null; - Boolean vibrate = Boolean.FALSE; + boolean vibrate = false; + boolean insistent = false; + String group = null; + boolean localOnly = true; + int priority = 0; Map notificationSettings = new Gson().fromJson(TiApplication.getInstance().getAppProperties().getString(GCMModule.NOTIFICATION_SETTINGS, null), Map.class); if (notificationSettings != null) { @@ -115,6 +119,39 @@ protected void onMessage(Context context, Intent intent) { Log.e(LCAT, "Invalid setting vibrate, should be boolean"); } } + + if (notificationSettings.get("insistent") != null) { + if (notificationSettings.get("insistent") instanceof Boolean) { + insistent = (Boolean) notificationSettings.get("insistent"); + } else { + Log.e(LCAT, "Invalid setting insistent, should be boolean"); + } + } + + if (notificationSettings.get("group") != null) { + if (notificationSettings.get("group") instanceof String) { + group = (String) notificationSettings.get("group"); + } else { + Log.e(LCAT, "Invalid setting group, should be string"); + } + } + + if (notificationSettings.get("localOnly") != null) { + if (notificationSettings.get("localOnly") instanceof Boolean) { + localOnly = (Boolean) notificationSettings.get("localOnly"); + } else { + Log.e(LCAT, "Invalid setting localOnly, should be boolean"); + } + } + + if (notificationSettings.get("priority") != null) { + if (notificationSettings.get("priority") instanceof Integer) { + priority = (Integer) notificationSettings.get("priority"); + } else { + Log.e(LCAT, "Invalid setting priority, should be int, between PRIORITY_MIN (" + NotificationCompat.PRIORITY_MIN + ") and PRIORITY_MAX (" + NotificationCompat.PRIORITY_MAX + ")"); + } + } + } else { Log.d(LCAT, "No notification settings found"); } @@ -151,41 +188,77 @@ protected void onMessage(Context context, Intent intent) { Log.d(LCAT, "No large icon found"); } - Notification notification = new NotificationCompat.Builder(context) + NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .setContentTitle(title) .setContentText(message) .setTicker(ticker) .setContentIntent(contentIntent) .setSmallIcon(smallIcon) - .setLargeIcon(bitmap).build(); + .setLargeIcon(bitmap); + + /* Name of group to group similar notifications together, can also be set in the push notification payload */ + if (data.get("group") != null) { + group = (String) data.get("group"); + } + if (group != null) { + builder = builder.setGroup(group); + } + Log.i(LCAT, "Group: " + group); + + /* Whether notification should be for this device only or bridged to other devices, can also be set in the push notification payload */ + if (data.get("localOnly") != null) { + localOnly = Boolean.getBoolean((String) data.get("localOnly")); + } + builder = builder.setLocalOnly(localOnly); + Log.i(LCAT, "LocalOnly: " + localOnly); + + /* Specify notification priority, can also be set in the push notification payload */ + if (data.get("priority") != null) { + priority = Integer.parseInt((String) data.get("priority")); + } + if (priority >= NotificationCompat.PRIORITY_MIN && priority <= NotificationCompat.PRIORITY_MAX) { + builder.setPriority(priority); + Log.i(LCAT, "Priority: " + priority); + } else { + Log.e(LCAT, "Ignored invalid priority " + priority); + } - // Sound + Notification notification = builder.build(); + + /* Sound, can also be set in the push notification payload */ if (data.get("sound") != null) { Log.d(LCAT, "Sound specified in notification"); sound = (String) data.get("sound"); } if ("default".equals(sound)) { - Log.i(LCAT, "Notification: default sound"); + Log.i(LCAT, "Sound: default sound"); notification.defaults |= Notification.DEFAULT_SOUND; } else if (sound != null) { - Log.i(LCAT, "Notification: sound " + sound); + Log.i(LCAT, "Sound " + sound); notification.sound = Uri.parse("android.resource://" + pkg + "/" + getResource("raw", sound)); } - /* Vibrate */ + /* Vibrate, can also be set in the push notification payload */ if (data.get("vibrate") != null) { vibrate = Boolean.getBoolean((String) data.get("vibrate")); - } if (vibrate) { notification.defaults |= Notification.DEFAULT_VIBRATE; } - Log.i(LCAT, "Vibrate: " + vibrate); + /* Insistent, can also be set in the push notification payload */ + if ("true".equals(data.get("insistent"))) { + insistent = true; + } + if (insistent) { + notification.flags |= Notification.FLAG_INSISTENT; + } + Log.i(LCAT, "Insistent: " + insistent); + notification.defaults |= Notification.DEFAULT_LIGHTS; - notification.flags = Notification.FLAG_AUTO_CANCEL; + notification.flags |= Notification.FLAG_AUTO_CANCEL; ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(1, notification); } diff --git a/src/nl/vanvianen/android/gcm/GCMModule.java b/src/nl/vanvianen/android/gcm/GCMModule.java index ff01fad..ea263d0 100644 --- a/src/nl/vanvianen/android/gcm/GCMModule.java +++ b/src/nl/vanvianen/android/gcm/GCMModule.java @@ -1,11 +1,3 @@ -/** - * This file was auto-generated by the Titanium Module SDK helper for Android - * Appcelerator Titanium Mobile - * Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved. - * Licensed under the terms of the Apache Public License - * Please see the LICENSE included with this distribution for details. - */ - package nl.vanvianen.android.gcm; import android.app.Activity; diff --git a/timodule.xml b/timodule.xml index da58ee1..075ee6c 100644 --- a/timodule.xml +++ b/timodule.xml @@ -1,9 +1,7 @@ - - - + @@ -21,9 +19,7 @@ - - @@ -41,7 +37,6 @@ -