Skip to content

Commit 4f0086b

Browse files
authored
Summary body and title overriding (#242)
* The following fixes are for pre-Android 7 devices, wasn't an issue on this version of Android. * Reads overridden title & body from notification extenders and uses it for summary notifications * Fixed issue with custom sound not playing on the 2nd summary notification or both default and custom playing.
1 parent 42cb50e commit 4f0086b

File tree

5 files changed

+217
-33
lines changed

5 files changed

+217
-33
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/GenerateNotification.java

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private static class OneSignalNotificationBuilder {
8080
boolean hasLargeIcon;
8181
}
8282

83-
static void setStatics(Context inContext) {
83+
private static void setStatics(Context inContext) {
8484
currentContext = inContext;
8585
packageName = currentContext.getPackageName();
8686
contextResources = currentContext.getResources();
@@ -313,8 +313,18 @@ private static void showNotification(NotificationGenerationJob notifJob) {
313313
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Could not set background notification image!", t);
314314
}
315315

316-
if (notifJob.overrideSettings != null && notifJob.overrideSettings.extender != null)
316+
if (notifJob.overrideSettings != null && notifJob.overrideSettings.extender != null) {
317+
notifJob.orgFlags = notifBuilder.mNotification.flags;
318+
notifJob.orgSound = notifBuilder.mNotification.sound;
317319
notifBuilder.extend(notifJob.overrideSettings.extender);
320+
321+
notifJob.overriddenBodyFromExtender = notifBuilder.mContentText;
322+
notifJob.overriddenTitleFromExtender = notifBuilder.mContentTitle;
323+
if (!notifJob.restoring) {
324+
notifJob.overriddenFlags = notifBuilder.mNotification.flags;
325+
notifJob.overriddenSound = notifBuilder.mNotification.sound;
326+
}
327+
}
318328

319329
// Keeps notification from playing sound + vibrating again
320330
if (notifJob.restoring)
@@ -329,7 +339,8 @@ private static void showNotification(NotificationGenerationJob notifJob) {
329339
notifBuilder.setDeleteIntent(deleteIntent);
330340
notifBuilder.setGroup(group);
331341

332-
notification = notifBuilder.build();
342+
notification = createSingleNotificationBeforeSummaryBuilder(notifJob, notifBuilder);
343+
333344
createSummaryNotification(notifJob, oneSignalNotificationBuilder);
334345
}
335346
else {
@@ -351,6 +362,28 @@ private static void showNotification(NotificationGenerationJob notifJob) {
351362
NotificationManagerCompat.from(currentContext).notify(notificationId, notification);
352363
}
353364
}
365+
366+
// Removes custom sound set from the extender from non-summary notification before building it.
367+
// This prevents the sound from playing twice or both the default sound + a custom one.
368+
private static Notification createSingleNotificationBeforeSummaryBuilder(NotificationGenerationJob notifJob, NotificationCompat.Builder notifBuilder) {
369+
// Includes Android 4.3 through 6.0.1. Android 7.1 handles this correctly without this.
370+
// Android 4.2 and older just post the summary only.
371+
boolean singleNotifWorkArounds = Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1 && Build.VERSION.SDK_INT <Build.VERSION_CODES.N && !notifJob.restoring;
372+
373+
if (singleNotifWorkArounds) {
374+
if (notifJob.overriddenSound != null && !notifJob.overriddenSound.equals(notifJob.orgSound))
375+
notifBuilder.setSound(null);
376+
}
377+
378+
Notification notification = notifBuilder.build();
379+
380+
381+
if (singleNotifWorkArounds) {
382+
notifBuilder.setSound(notifJob.overriddenSound);
383+
}
384+
385+
return notification;
386+
}
354387

355388
// Xiaomi requires the following to show a custom notification icons.
356389
// Without this MIUI 8 will only show the app icon on the left.
@@ -382,7 +415,7 @@ static void updateSummaryNotification(NotificationGenerationJob notifJob) {
382415
}
383416

384417
// This summary notification will be visible instead of the normal one on pre-Android 7.0 devices.
385-
static void createSummaryNotification(NotificationGenerationJob notifJob, OneSignalNotificationBuilder notifBuilder) {
418+
private static void createSummaryNotification(NotificationGenerationJob notifJob, OneSignalNotificationBuilder notifBuilder) {
386419
boolean updateSummary = notifJob.restoring;
387420
JSONObject gcmBundle = notifJob.jsonPayload;
388421

@@ -493,6 +526,13 @@ static void createSummaryNotification(NotificationGenerationJob notifJob, OneSig
493526
NotificationCompat.Builder summaryBuilder = getBaseOneSignalNotificationBuilder(notifJob).compatBuilder;
494527
if (updateSummary)
495528
removeNotifyOptions(summaryBuilder);
529+
else {
530+
if (notifJob.overriddenSound != null)
531+
summaryBuilder.setSound(notifJob.overriddenSound);
532+
533+
if (notifJob.overriddenFlags != null)
534+
summaryBuilder.setDefaults(notifJob.overriddenFlags);
535+
}
496536

497537
// The summary is designed to fit all notifications.
498538
// Default small and large icons are used instead of the payload options to enforce this.
@@ -514,14 +554,18 @@ static void createSummaryNotification(NotificationGenerationJob notifJob, OneSig
514554

515555
// Add the latest notification to the summary
516556
if (!updateSummary) {
517-
String line1Title = gcmBundle.optString("title", null);
557+
String line1Title = null;
558+
559+
if (notifJob.getTitle() != null)
560+
line1Title = notifJob.getTitle().toString();
518561

519562
if (line1Title == null)
520563
line1Title = "";
521564
else
522565
line1Title += " ";
523-
524-
String message = gcmBundle.optString("alert");
566+
567+
String message = notifJob.getBody().toString();
568+
525569
SpannableString spannableString = new SpannableString(line1Title + message);
526570
if (line1Title.length() > 0)
527571
spannableString.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, line1Title.length(), 0);

OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static int Process(NotificationGenerationJob notifJob) {
8585
GenerateNotification.fromJsonPayload(notifJob);
8686

8787
if (!notifJob.restoring) {
88-
saveNotification(notifJob.context, notifJob.jsonPayload, false, notifJob.getAndroidId());
88+
saveNotification(notifJob, false);
8989
try {
9090
JSONObject jsonObject = new JSONObject(notifJob.jsonPayload.toString());
9191
jsonObject.put("notificationId", notifJob.getAndroidId());
@@ -104,20 +104,28 @@ static JSONArray bundleAsJsonArray(Bundle bundle) {
104104

105105

106106
static void saveNotification(Context context, Bundle bundle, boolean opened, int notificationId) {
107-
saveNotification(context, bundleAsJSONObject(bundle), opened, notificationId);
107+
NotificationGenerationJob notifJob = new NotificationGenerationJob(context);
108+
notifJob.jsonPayload = bundleAsJSONObject(bundle);
109+
notifJob.overrideSettings = new NotificationExtenderService.OverrideSettings();
110+
notifJob.overrideSettings.androidNotificationId = notificationId;
111+
112+
saveNotification(notifJob, opened);
108113
}
109-
114+
110115
// Saving the notification provides the following:
111116
// * Prevent duplicates
112117
// * Build summary notifications
113118
// * Collapse key / id support - Used to lookup the android notification id later
114119
// * Redisplay notifications after reboot, upgrade of app, or cold boot after a force kill.
115120
// * Future - Public API to get a list of notifications
116-
static void saveNotification(Context context, JSONObject jsonPayload, boolean opened, int notificationId) {
121+
static void saveNotification(NotificationGenerationJob notifiJob, boolean opened) {
122+
Context context = notifiJob.context;
123+
JSONObject jsonPayload = notifiJob.jsonPayload;
124+
117125
try {
118-
JSONObject customJSON = new JSONObject(jsonPayload.optString("custom"));
126+
JSONObject customJSON = new JSONObject(notifiJob.jsonPayload.optString("custom"));
119127

120-
OneSignalDbHelper dbHelper = OneSignalDbHelper.getInstance(context);
128+
OneSignalDbHelper dbHelper = OneSignalDbHelper.getInstance(notifiJob.context);
121129
SQLiteDatabase writableDb = null;
122130

123131
try {
@@ -129,8 +137,8 @@ static void saveNotification(Context context, JSONObject jsonPayload, boolean op
129137

130138
// Count any notifications with duplicated android notification ids as dismissed.
131139
// -1 is used to note never displayed
132-
if (notificationId != -1) {
133-
String whereStr = NotificationTable.COLUMN_NAME_ANDROID_NOTIFICATION_ID + " = " + notificationId;
140+
if (notifiJob.overrideSettings.androidNotificationId != -1) {
141+
String whereStr = NotificationTable.COLUMN_NAME_ANDROID_NOTIFICATION_ID + " = " + notifiJob.overrideSettings.androidNotificationId;
134142

135143
ContentValues values = new ContentValues();
136144
values.put(NotificationTable.COLUMN_NAME_DISMISSED, 1);
@@ -149,11 +157,11 @@ static void saveNotification(Context context, JSONObject jsonPayload, boolean op
149157

150158
values.put(NotificationTable.COLUMN_NAME_OPENED, opened ? 1 : 0);
151159
if (!opened)
152-
values.put(NotificationTable.COLUMN_NAME_ANDROID_NOTIFICATION_ID, notificationId);
153-
154-
if (jsonPayload.has("title"))
155-
values.put(NotificationTable.COLUMN_NAME_TITLE, jsonPayload.optString("title"));
156-
values.put(NotificationTable.COLUMN_NAME_MESSAGE, jsonPayload.optString("alert"));
160+
values.put(NotificationTable.COLUMN_NAME_ANDROID_NOTIFICATION_ID, notifiJob.overrideSettings.androidNotificationId);
161+
162+
if (notifiJob.getTitle() != null)
163+
values.put(NotificationTable.COLUMN_NAME_TITLE, notifiJob.getTitle().toString());
164+
values.put(NotificationTable.COLUMN_NAME_MESSAGE, notifiJob.getBody().toString());
157165

158166
values.put(NotificationTable.COLUMN_NAME_FULL_DATA, jsonPayload.toString());
159167

OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationExtenderService.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,12 @@ void processJsonObject(JSONObject currentJsonPayload, boolean restoring) {
173173

174174
if (!display) {
175175
if (!restoring) {
176-
NotificationBundleProcessor.saveNotification(this, currentJsonPayload, true, -1);
176+
NotificationGenerationJob notifJob = new NotificationGenerationJob(this);
177+
notifJob.jsonPayload = currentJsonPayload;
178+
notifJob.overrideSettings = new OverrideSettings();
179+
notifJob.overrideSettings.androidNotificationId = -1;
180+
181+
NotificationBundleProcessor.saveNotification(notifJob, true);
177182
OneSignal.handleNotificationReceived(NotificationBundleProcessor.newJsonArray(currentJsonPayload), false, false);
178183
}
179184
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationGenerationJob.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030

3131
import android.content.Context;
32+
import android.net.Uri;
3233

3334
import org.json.JSONObject;
3435

@@ -43,12 +44,31 @@ class NotificationGenerationJob {
4344

4445
Long shownTimeStamp;
4546

47+
CharSequence overriddenBodyFromExtender;
48+
CharSequence overriddenTitleFromExtender;
49+
Uri overriddenSound;
50+
Integer overriddenFlags;
51+
Integer orgFlags;
52+
Uri orgSound;
53+
4654
NotificationGenerationJob(Context context) {
4755
this.context = context;
4856
}
4957

5058
NotificationExtenderService.OverrideSettings overrideSettings;
5159

60+
CharSequence getTitle() {
61+
if (overriddenTitleFromExtender != null)
62+
return overriddenTitleFromExtender;
63+
return jsonPayload.optString("title", null);
64+
}
65+
66+
CharSequence getBody() {
67+
if (overriddenBodyFromExtender != null)
68+
return overriddenBodyFromExtender;
69+
return jsonPayload.optString("alert", null);
70+
}
71+
5272
Integer getAndroidId() {
5373
if (overrideSettings == null)
5474
overrideSettings = new NotificationExtenderService.OverrideSettings();

0 commit comments

Comments
 (0)