Skip to content

Commit

Permalink
Refactor key extraction into single method.
Browse files Browse the repository at this point in the history
This change moves all alternative key logic into a single method.
Allows message keys to be in nested in "data" or "message" object. This is to support parse.com and other providers.
Added additional keys to support Urban Airship.

fixes phonegap#147 replaces phonegap#218 and phonegap#182
  • Loading branch information
smdvdsn committed Oct 13, 2015
1 parent a69b596 commit 0ef209c
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 76 deletions.
176 changes: 123 additions & 53 deletions src/android/com/adobe/phonegap/push/GCMIntentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;

@SuppressLint("NewApi")
Expand Down Expand Up @@ -62,6 +63,8 @@ public void onMessageReceived(String from, Bundle extras) {
SharedPreferences prefs = getApplicationContext().getSharedPreferences(PushPlugin.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE);
boolean forceShow = prefs.getBoolean(FORCE_SHOW, false);

normalizeExtras(extras);

// if we are in the foreground and forceShow is `false` only send data
if (!forceShow && PushPlugin.isInForeground()) {
extras.putBoolean(FOREGROUND, true);
Expand All @@ -81,12 +84,103 @@ else if (forceShow && PushPlugin.isInForeground()) {
}
}
}


/*
* Change a values key in the extras bundle
*/
private void replaceKey(String oldKey, String newKey, Bundle extras) {
Object value = extras.get(oldKey);
if ( value != null ) {
extras.remove(oldKey);
if (value instanceof String) {
extras.putString(newKey, (String) value);
} else if (value instanceof Boolean) {
extras.putBoolean(newKey, (Boolean) value);
} else if (value instanceof Number) {
extras.putDouble(newKey, ((Number) value).doubleValue());
} else {
extras.putString(newKey, String.valueOf(value));
}
}
}

/*
* Replace alternate keys with our canonical value
*/
private String normalizeKey(String key) {
if (key.equals(BODY) || key.equals(ALERT)) {
return MESSAGE;
} else if (key.equals(MSGCNT) || key.equals(BADGE)) {
return COUNT;
} else if (key.equals(SOUNDNAME)) {
return SOUND;
} else if (key.startsWith(GCM_NOTIFICATION)) {
return key.substring(GCM_NOTIFICATION.length()+1, key.length());
} else if (key.startsWith(GCM_N)) {
return key.substring(GCM_N.length()+1, key.length());
} else if (key.startsWith(UA_PREFIX)) {
key = key.substring(UA_PREFIX.length()+1, key.length());
return key.toLowerCase();
} else {
return key;
}
}

/*
* Parse bundle into normalized keys.
*/
private void normalizeExtras(Bundle extras) {
Log.d(LOG_TAG, "mormalize extras");
Iterator<String> it = extras.keySet().iterator();
while (it.hasNext()) {
String key = it.next();

Log.d(LOG_TAG, "key = " + key);

// If the key is "data" or "message" and the value is a json object extract
// This is to support parse.com and other services. Issue #147 and pull #218
if (key.equals(PARSE_COM_DATA) || key.equals(MESSAGE)) {
Object json = extras.get(key);
// Make sure data is json object stringified
if ( json instanceof String && ((String) json).startsWith("{") ) {
Log.d(LOG_TAG, "extracting nested message data from key = " + key);
try {
// If object contains message keys promote each value to the root of the bundle
JSONObject data = new JSONObject((String) json);
if ( data.has(ALERT) || data.has(MESSAGE) || data.has(BODY) || data.has(TITLE) ) {
Iterator<String> jsonIter = data.keys();
while (jsonIter.hasNext()) {
String jsonKey = jsonIter.next();

Log.d(LOG_TAG, "key = data/" + jsonKey);

String value = data.getString(jsonKey);
jsonKey = normalizeKey(jsonKey);
extras.putString(jsonKey, value);
}

extras.remove(key);
}
} catch( JSONException e) {
Log.e(LOG_TAG, "normalizeExtras: JSON exception");
}
}
}

String newKey = normalizeKey(key);
if ( !key.equals(newKey) ) {
Log.d(LOG_TAG, "replace key " + key + " with " + newKey);
replaceKey(key, newKey, extras);
}
} // while

}

private void showNotificationIfPossible (Context context, Bundle extras) {

// Send a notification if there is a message or title, otherwise just send data
String message = this.getMessageText(extras);
String title = getString(extras, TITLE, "");
String message = extras.getString(MESSAGE);
String title = extras.getString(TITLE);
if ((message != null && message.length() != 0) ||
(title != null && title.length() != 0)) {
createNotification(context, extras);
Expand All @@ -113,8 +207,8 @@ public void createNotification(Context context, Bundle extras) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setWhen(System.currentTimeMillis())
.setContentTitle(getString(extras, TITLE))
.setTicker(getString(extras, TITLE))
.setContentTitle(extras.getString(TITLE))
.setTicker(extras.getString(TITLE))
.setContentIntent(contentIntent)
.setAutoCancel(true);

Expand All @@ -141,7 +235,7 @@ public void createNotification(Context context, Bundle extras) {
* To use, add the `iconColor` key to plugin android options
*
*/
setNotificationIconColor(getString(extras,"color"), mBuilder, localIconColor);
setNotificationIconColor(extras.getString("color"), mBuilder, localIconColor);

/*
* Notification Icon
Expand Down Expand Up @@ -208,7 +302,7 @@ public void createNotification(Context context, Bundle extras) {

private void createActions(Bundle extras, NotificationCompat.Builder mBuilder, Resources resources, String packageName) {
Log.d(LOG_TAG, "create actions");
String actions = getString(extras, ACTIONS);
String actions = extras.getString(ACTIONS);
if (actions != null) {
try {
JSONArray actionsArray = new JSONArray(actions);
Expand All @@ -231,17 +325,17 @@ private void createActions(Bundle extras, NotificationCompat.Builder mBuilder, R
}

private void setNotificationCount(Bundle extras, NotificationCompat.Builder mBuilder) {
String msgcnt = getString(extras, MSGCNT);
String msgcnt = extras.getString(MSGCNT);
if (msgcnt == null) {
msgcnt = getString(extras, BADGE);
msgcnt = extras.getString(BADGE);
}
if (msgcnt != null) {
mBuilder.setNumber(Integer.parseInt(msgcnt));
}
}

private void setNotificationVibration(Bundle extras, Boolean vibrateOption, NotificationCompat.Builder mBuilder) {
String vibrationPattern = getString(extras, VIBRATION_PATTERN);
String vibrationPattern = extras.getString(VIBRATION_PATTERN);
if (vibrationPattern != null) {
String[] items = vibrationPattern.replaceAll("\\[", "").replaceAll("\\]", "").split(",");
long[] results = new long[items.length];
Expand All @@ -259,9 +353,9 @@ private void setNotificationVibration(Bundle extras, Boolean vibrateOption, Noti
}

private void setNotificationMessage(int notId, Bundle extras, NotificationCompat.Builder mBuilder) {
String message = getMessageText(extras);
String message = extras.getString(MESSAGE);

String style = getString(extras, STYLE, STYLE_TEXT);
String style = extras.getString(STYLE, STYLE_TEXT);
if(STYLE_INBOX.equals(style)) {
setNotification(notId, message);

Expand All @@ -272,12 +366,12 @@ private void setNotificationMessage(int notId, Bundle extras, NotificationCompat
if (sizeList > 1) {
String sizeListMessage = sizeList.toString();
String stacking = sizeList + " more";
if (getString(extras, SUMMARY_TEXT) != null) {
stacking = getString(extras, SUMMARY_TEXT);
if (extras.getString(SUMMARY_TEXT) != null) {
stacking = extras.getString(SUMMARY_TEXT);
stacking = stacking.replace("%n%", sizeListMessage);
}
NotificationCompat.InboxStyle notificationInbox = new NotificationCompat.InboxStyle()
.setBigContentTitle(getString(extras, TITLE))
.setBigContentTitle(extras.getString(TITLE))
.setSummaryText(stacking);

for (int i = messageList.size() - 1; i >= 0; i--) {
Expand All @@ -289,19 +383,19 @@ private void setNotificationMessage(int notId, Bundle extras, NotificationCompat
NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
if (message != null) {
bigText.bigText(message);
bigText.setBigContentTitle(getString(extras, TITLE));
bigText.setBigContentTitle(extras.getString(TITLE));
mBuilder.setStyle(bigText);
}
}
} else if (STYLE_PICTURE.equals(style)) {
setNotification(notId, "");

NotificationCompat.BigPictureStyle bigPicture = new NotificationCompat.BigPictureStyle();
bigPicture.bigPicture(getBitmapFromURL(getString(extras, PICTURE)));
bigPicture.setBigContentTitle(getString(extras, TITLE));
bigPicture.setSummaryText(getString(extras, SUMMARY_TEXT));
bigPicture.bigPicture(getBitmapFromURL(extras.getString(PICTURE)));
bigPicture.setBigContentTitle(extras.getString(TITLE));
bigPicture.setSummaryText(extras.getString(SUMMARY_TEXT));

mBuilder.setContentTitle(getString(extras, TITLE));
mBuilder.setContentTitle(extras.getString(TITLE));
mBuilder.setContentText(message);

mBuilder.setStyle(bigPicture);
Expand All @@ -314,9 +408,9 @@ private void setNotificationMessage(int notId, Bundle extras, NotificationCompat
mBuilder.setContentText(Html.fromHtml(message));

bigText.bigText(message);
bigText.setBigContentTitle(getString(extras, TITLE));
bigText.setBigContentTitle(extras.getString(TITLE));

String summaryText = getString(extras, SUMMARY_TEXT);
String summaryText = extras.getString(SUMMARY_TEXT);
if (summaryText != null) {
bigText.setSummaryText(summaryText);
}
Expand All @@ -331,34 +425,10 @@ private void setNotificationMessage(int notId, Bundle extras, NotificationCompat
}
}

private String getString(Bundle extras,String key) {
String message = extras.getString(key);
if (message == null) {
message = extras.getString(GCM_NOTIFICATION+"."+key);
}
return message;
}

private String getString(Bundle extras,String key, String defaultString) {
String message = extras.getString(key);
if (message == null) {
message = extras.getString(GCM_NOTIFICATION+"."+key, defaultString);
}
return message;
}

private String getMessageText(Bundle extras) {
String message = getString(extras, MESSAGE);
if (message == null) {
message = getString(extras, BODY);
}
return message;
}

private void setNotificationSound(Context context, Bundle extras, NotificationCompat.Builder mBuilder) {
String soundname = getString(extras, SOUNDNAME);
String soundname = extras.getString(SOUNDNAME);
if (soundname == null) {
soundname = getString(extras, SOUND);
soundname = extras.getString(SOUND);
}
if (soundname != null) {
Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
Expand All @@ -371,7 +441,7 @@ private void setNotificationSound(Context context, Bundle extras, NotificationCo
}

private void setNotificationLedColor(Bundle extras, NotificationCompat.Builder mBuilder) {
String ledColor = getString(extras, LED_COLOR);
String ledColor = extras.getString(LED_COLOR);
if (ledColor != null) {
// Converts parse Int Array from ledColor
String[] items = ledColor.replaceAll("\\[", "").replaceAll("\\]", "").split(",");
Expand All @@ -390,7 +460,7 @@ private void setNotificationLedColor(Bundle extras, NotificationCompat.Builder m
}

private void setNotificationPriority(Bundle extras, NotificationCompat.Builder mBuilder) {
String priorityStr = getString(extras, PRIORITY);
String priorityStr = extras.getString(PRIORITY);
if (priorityStr != null) {
try {
Integer priority = Integer.parseInt(priorityStr);
Expand All @@ -406,7 +476,7 @@ private void setNotificationPriority(Bundle extras, NotificationCompat.Builder m
}

private void setNotificationLargeIcon(Bundle extras, String packageName, Resources resources, NotificationCompat.Builder mBuilder) {
String gcmLargeIcon = getString(extras, IMAGE); // from gcm
String gcmLargeIcon = extras.getString(IMAGE); // from gcm
if (gcmLargeIcon != null) {
if (gcmLargeIcon.startsWith("http://") || gcmLargeIcon.startsWith("https://")) {
mBuilder.setLargeIcon(getBitmapFromURL(gcmLargeIcon));
Expand Down Expand Up @@ -436,7 +506,7 @@ private void setNotificationLargeIcon(Bundle extras, String packageName, Resourc

private void setNotificationSmallIcon(Context context, Bundle extras, String packageName, Resources resources, NotificationCompat.Builder mBuilder, String localIcon) {
int iconId = 0;
String icon = getString(extras, ICON);
String icon = extras.getString(ICON);
if (icon != null) {
iconId = resources.getIdentifier(icon, DRAWABLE, packageName);
Log.d(LOG_TAG, "using icon from plugin options");
Expand Down Expand Up @@ -496,7 +566,7 @@ private int parseInt(String value, Bundle extras) {
int retval = 0;

try {
retval = Integer.parseInt(getString(extras, value));
retval = Integer.parseInt(extras.getString(value));
}
catch(NumberFormatException e) {
Log.e(LOG_TAG, "Number format exception - Error parsing " + value + ": " + e.getMessage());
Expand Down
4 changes: 4 additions & 0 deletions src/android/com/adobe/phonegap/push/PushConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ public interface PushConstants {
public static final String STYLE = "style";
public static final String SUMMARY_TEXT = "summaryText";
public static final String PICTURE = "picture";
public static final String GCM_N = "gcm.n.";
public static final String GCM_NOTIFICATION = "gcm.notification";
public static final String UA_PREFIX = "com.urbanairship.push";
public static final String PARSE_COM_DATA = "data";
public static final String ALERT = "alert";
public static final String MESSAGE = "message";
public static final String BODY = "body";
public static final String SOUNDNAME = "soundname";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private void processPushBundle(boolean isPushPluginActive) {

originalExtras.putBoolean(FOREGROUND, false);
originalExtras.putBoolean(COLDSTART, !isPushPluginActive);
originalExtras.putString(CALLBACK, getIntent().getExtras().getString("callback"));
originalExtras.putString(CALLBACK, extras.getString("callback"));

PushPlugin.sendExtras(originalExtras);
}
Expand Down
Loading

0 comments on commit 0ef209c

Please sign in to comment.