Skip to content

Commit

Permalink
New version with additional properties to specified in either the not…
Browse files Browse the repository at this point in the history
…ification 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
  • Loading branch information
morinel committed Sep 8, 2015
1 parent c77aaa0 commit 6529a9d
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 38 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Expand Up @@ -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.
Expand Down
24 changes: 17 additions & 7 deletions 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.
14 changes: 9 additions & 5 deletions example/app.js
Expand Up @@ -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) {
Expand All @@ -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
});
Expand Down
2 changes: 1 addition & 1 deletion manifest
Expand Up @@ -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 <jeroen@vanvianen.nl>
Expand Down
93 changes: 83 additions & 10 deletions src/nl/vanvianen/android/gcm/GCMIntentService.java
Expand Up @@ -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<String, Object> notificationSettings = new Gson().fromJson(TiApplication.getInstance().getAppProperties().getString(GCMModule.NOTIFICATION_SETTINGS, null), Map.class);
if (notificationSettings != null) {
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 0 additions & 8 deletions 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;
Expand Down
7 changes: 1 addition & 6 deletions timodule.xml
@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ti:module xmlns:ti="http://ti.appcelerator.org" xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Similar to tiapp.xml, but contains module/platform specific configuration in <iphone> and <android>/<android:manifest> sections -->

<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest package="com.activate.gcm" android:versionCode="1" android:versionName="1.0" android:installLocation="internalOnly">
<manifest package="nl.vanvianen.android.gcm" android:versionCode="2" android:versionName="1.1" android:installLocation="internalOnly">
<supports-screens android:anyDensity="true"/>
<uses-sdk android:minSdkVersion="10"/>

Expand All @@ -21,9 +19,7 @@

<application>
<service android:name="nl.vanvianen.android.gcm.GCMIntentService" />

<receiver android:name="nl.vanvianen.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">

<!-- Start receiver on boot -->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
Expand All @@ -41,7 +37,6 @@
<category android:name="${tiapp.properties['id']}" />
</intent-filter>
</receiver>

</application>
</manifest>
</android>
Expand Down

0 comments on commit 6529a9d

Please sign in to comment.