Skip to content

Commit c2f79fa

Browse files
committed
NotificationExtenderService now started from an Alarm
* Starting a service from the background is compatible with Android O * Changing to a JobScheduler would break interface compatibility with apps extending the class
1 parent 970eb89 commit c2f79fa

File tree

4 files changed

+50
-58
lines changed

4 files changed

+50
-58
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public void onReceive(Context context, Intent intent) {
7878
// OR app developer setup a extender service to handle the notification.
7979
if (processedResult.isDup || processedResult.hasExtenderService) {
8080
// Abort to prevent other GCM receivers from process this Intent.
81-
abortBroadcast();
81+
setAbort();
8282
return;
8383
}
8484

@@ -87,8 +87,7 @@ public void onReceive(Context context, Intent intent) {
8787
// AND the setting is enabled to allow filtering in this case.
8888
if (processedResult.isOneSignalPayload &&
8989
OneSignal.getFilterOtherGCMReceivers(context)) {
90-
91-
abortBroadcast();
90+
setAbort();
9291
return;
9392
}
9493

@@ -99,6 +98,11 @@ private void setResult(int code) {
9998
if (isOrderedBroadcast())
10099
setResultCode(code);
101100
}
101+
102+
private void setAbort() {
103+
if (isOrderedBroadcast())
104+
abortBroadcast();
105+
}
102106

103107
private static ProcessedBundleResult processOrderBroadcast(Context context, Intent intent, Bundle bundle) {
104108
if (!isGcmMessage(intent))

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

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
import com.onesignal.OneSignalDbContract.NotificationTable;
3535

36+
import android.app.AlarmManager;
37+
import android.app.PendingIntent;
3638
import android.content.ContentValues;
3739
import android.content.Context;
3840
import android.content.Intent;
@@ -376,17 +378,9 @@ static ProcessedBundleResult processBundle(Context context, final Bundle bundle)
376378
result.isOneSignalPayload = true;
377379

378380
prepareBundle(bundle);
379-
380-
// NotificationExtenderService still makes additional checks such as notValidOrDuplicated
381-
Intent overrideIntent = NotificationExtenderService.getIntent(context);
382-
if (overrideIntent != null) {
383-
overrideIntent.putExtra("json_payload", bundleAsJSONObject(bundle).toString());
384-
overrideIntent.putExtra("timestamp", System.currentTimeMillis() / 1000L);
385-
WakefulBroadcastReceiver.startWakefulService(context, overrideIntent);
386-
result.hasExtenderService = true;
387-
return result;
388-
}
389-
381+
382+
if (startExtenderService(context, bundle, result)) return result;
383+
390384
// We already ran a getNotificationIdFromGCMBundle == null check above so this will only be true for dups
391385
result.isDup = OneSignal.notValidOrDuplicated(context, bundleAsJSONObject(bundle));
392386
if (result.isDup)
@@ -410,6 +404,24 @@ public void run() {
410404
return result;
411405
}
412406

407+
// NotificationExtenderService still makes additional checks such as notValidOrDuplicated
408+
private static boolean startExtenderService(Context context, Bundle bundle, ProcessedBundleResult result) {
409+
Intent intent = NotificationExtenderService.getIntent(context);
410+
if (intent == null) return false;
411+
412+
intent.putExtra("json_payload", bundleAsJSONObject(bundle).toString());
413+
intent.putExtra("timestamp", System.currentTimeMillis() / 1000L);
414+
415+
// Using Alarm with a short delay for Android O compatibility
416+
long atTime = System.currentTimeMillis() + 100;
417+
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
418+
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
419+
alarm.set(AlarmManager.RTC_WAKEUP, atTime, pendingIntent);
420+
421+
result.hasExtenderService = true;
422+
return true;
423+
}
424+
413425
static boolean shouldDisplay(boolean hasBody) {
414426
boolean showAsAlert = OneSignal.getInAppAlertNotificationEnabled();
415427
boolean isActive = OneSignal.isAppActive();

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

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@
5353
</service>
5454
*/
5555

56-
// TODO: This class can no longer extend IntentService. Nor can we change it to JobService.
57-
// It will be called from the respective server / job instead.
58-
public abstract class NotificationExtenderService {
56+
public abstract class NotificationExtenderService extends IntentService {
5957

6058
public static class OverrideSettings {
6159
public NotificationCompat.Extender extender;
@@ -75,6 +73,11 @@ void override(OverrideSettings overrideSettings) {
7573
}
7674
}
7775

76+
public NotificationExtenderService() {
77+
super("NotificationExtenderService");
78+
setIntentRedelivery(true);
79+
}
80+
7881
private OSNotificationDisplayedResult osNotificationDisplayedResult;
7982
private JSONObject currentJsonPayload;
8083
private boolean currentlyRestoring;
@@ -90,19 +93,20 @@ protected final OSNotificationDisplayedResult displayNotification(OverrideSettin
9093

9194
overrideSettings.override(currentBaseOverrideSettings);
9295
osNotificationDisplayedResult = new OSNotificationDisplayedResult();
93-
96+
9497
NotificationGenerationJob notifJob = createNotifJobFromCurrent();
9598
notifJob.overrideSettings = overrideSettings;
96-
99+
97100
osNotificationDisplayedResult.androidNotificationId = NotificationBundleProcessor.Process(notifJob);
98101
return osNotificationDisplayedResult;
99102
}
100103

101104
// App developer must implement
102105
// - Return true to count it as processed which will prevent the default OneSignal SDK notification from displaying.
103106
protected abstract boolean onNotificationProcessing(OSNotificationReceivedResult notification);
104-
105-
final void onHandleIntent(Intent intent) {
107+
108+
@Override
109+
protected final void onHandleIntent(Intent intent) {
106110
processIntent(intent);
107111
GcmBroadcastReceiver.completeWakefulIntent(intent);
108112
}
@@ -119,7 +123,7 @@ private void processIntent(Intent intent) {
119123

120124
String jsonStrPayload = bundle.getString("json_payload");
121125
if (jsonStrPayload == null) {
122-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "json_payload key is nonexistent from mBundle passed to NotificationExtenderService: " + bundle);
126+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "json_payload key is nonexistent from bundle passed to NotificationExtenderService: " + bundle);
123127
return;
124128
}
125129

@@ -165,15 +169,15 @@ void processJsonObject(JSONObject currentJsonPayload, boolean restoring) {
165169
// Save as processed to prevent possible duplicate calls from canonical ids.
166170

167171
boolean display = !developerProcessed &&
168-
NotificationBundleProcessor.shouldDisplay(!"".equals(currentJsonPayload.optString("alert")));
172+
NotificationBundleProcessor.shouldDisplay(!"".equals(currentJsonPayload.optString("alert")));
169173

170174
if (!display) {
171175
if (!restoring) {
172176
NotificationGenerationJob notifJob = new NotificationGenerationJob(this);
173177
notifJob.jsonPayload = currentJsonPayload;
174178
notifJob.overrideSettings = new OverrideSettings();
175179
notifJob.overrideSettings.androidNotificationId = -1;
176-
180+
177181
NotificationBundleProcessor.saveNotification(notifJob, true);
178182
OneSignal.handleNotificationReceived(NotificationBundleProcessor.newJsonArray(currentJsonPayload), false, false);
179183
}
@@ -182,31 +186,24 @@ void processJsonObject(JSONObject currentJsonPayload, boolean restoring) {
182186
NotificationBundleProcessor.Process(createNotifJobFromCurrent());
183187
}
184188
}
185-
186-
private static Intent getIntentBase(Context context) {
187-
return new Intent().setAction("com.onesignal.NotificationExtender").setPackage(context.getPackageName());
188-
}
189-
190-
static List<ResolveInfo> getIntentResolveInfoList(Context context) {
191-
PackageManager packageManager = context.getPackageManager();
192-
return packageManager.queryIntentServices(getIntentBase(context), PackageManager.GET_META_DATA);
193-
}
194189

195190
static Intent getIntent(Context context) {
196-
List<ResolveInfo> resolveInfo = getIntentResolveInfoList(context);
191+
PackageManager packageManager = context.getPackageManager();
192+
Intent intent = new Intent().setAction("com.onesignal.NotificationExtender").setPackage(context.getPackageName());
193+
List<ResolveInfo> resolveInfo = packageManager.queryIntentServices(intent, PackageManager.GET_META_DATA);
197194
if (resolveInfo.size() < 1)
198195
return null;
199196

200-
return getIntentBase(context);
197+
return intent;
201198
}
202-
199+
203200
private NotificationGenerationJob createNotifJobFromCurrent() {
204201
NotificationGenerationJob notifJob = new NotificationGenerationJob(this);
205202
notifJob.restoring = currentlyRestoring;
206203
notifJob.jsonPayload = currentJsonPayload;
207204
notifJob.shownTimeStamp = restoreTimestamp;
208205
notifJob.overrideSettings = currentBaseOverrideSettings;
209-
206+
210207
return notifJob;
211208
}
212209
}

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

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)