NotificationServiceExtension
Allows customization of push notification behavior before display and when opened.
NotificationServiceExtension provides hook methods to intercept and modify push notification processing at key moments: when notifications are received, opened, canceled, or when notification groups are opened. This is the primary extension point for customizing how your app handles push notifications.
Key Features:
- Foreground Handling - Prevent notification display when app is in foreground
- Custom Launch Behavior - Control which activity opens when notification is tapped
- Deep Link Control - Override default URL/deep link handling
- Lifecycle Callbacks - Track notification open, cancel, and group open events
- Context Access - Access application context for custom logic
Note: For simple foreground suppression without any Java code, use the com.pushwoosh.foreground_push manifest metadata instead of subclassing. See setShowPushnotificationAlert for details.
Setup:
Pushwoosh and JSON imports used by the examples below:
import android.util.Log;
import com.pushwoosh.notification.NotificationServiceExtension;
import com.pushwoosh.notification.PushBundleDataProvider;
import com.pushwoosh.notification.PushMessage;
import org.json.JSONException;
import org.json.JSONObject;
1. Create a public class extending NotificationServiceExtension with a public no-args constructor:
public class MyNotificationService extends NotificationServiceExtension {
protected boolean onMessageReceived(PushMessage message) {
// Return true to suppress notification when app is in foreground
if (isAppOnForeground()) {
// Handle notification in-app (show dialog, update UI, etc.)
showInAppAlert(message.getMessage());
return true;
}
return false;
}
protected void onMessageOpened(PushMessage message) {
// Track notification open event
String customData = message.getCustomData();
if (customData != null) {
try {
String campaignId = new JSONObject(customData).optString("campaign_id", null);
Analytics.track("notification_opened", campaignId);
} catch (JSONException e) {
Log.e("App", "Failed to parse custom data", e);
}
}
}
}
2. Register your extension in AndroidManifest.xml:
<application>
<meta-data
android:name="com.pushwoosh.notification_service_extension"
android:value="com.your.package.MyNotificationService" />
</application>
Common Use Cases:Example 1: Suppress notifications when app is in foreground
protected boolean onMessageReceived(PushMessage message) {
if (isAppOnForeground()) {
// Show in-app notification instead
Context context = getApplicationContext();
Toast.makeText(context,
message.getMessage(),
Toast.LENGTH_LONG).show();
return true; // Notification won't be displayed
}
return false; // Show notification normally
}
Example 2: Launch specific activity based on notification data
protected void startActivityForPushMessage(PushMessage message) {
Context context = getApplicationContext();
String customData = message.getCustomData();
if (customData == null) {
super.startActivityForPushMessage(message);
return;
}
try {
JSONObject data = new JSONObject(customData);
String screenType = data.optString("screen");
Intent intent;
if ("product".equals(screenType)) {
// Open product details
intent = new Intent(context, ProductActivity.class);
String productId = data.optString("product_id", null);
intent.putExtra("productId", productId);
} else if ("cart".equals(screenType)) {
// Open shopping cart
intent = new Intent(context, CartActivity.class);
} else {
// Default behavior
super.startActivityForPushMessage(message);
return;
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
} catch (JSONException e) {
Log.e("App", "Failed to parse custom data", e);
super.startActivityForPushMessage(message);
}
}
Example 3: Handle notification cancel events
protected void onMessageCanceled(PushMessage message) {
// User dismissed notification - track in analytics
String customData = message.getCustomData();
if (customData != null) {
try {
String campaignId = new JSONObject(customData).optString("campaign_id", null);
Analytics.track("notification_dismissed", campaignId);
} catch (JSONException e) {
Log.e("App", "Failed to parse custom data", e);
}
}
// Update notification count
SharedPreferences prefs = getApplicationContext()
.getSharedPreferences("stats", Context.MODE_PRIVATE);
int dismissCount = prefs.getInt("dismiss_count", 0);
prefs.edit().putInt("dismiss_count", dismissCount + 1).apply();
}
Example 4: Override URL handling
protected boolean preHandleNotificationsWithUrl() {
// Return false to disable automatic URL/deep link handling
// You must handle URLs manually in startActivityForPushMessage()
return false;
}
protected void startActivityForPushMessage(PushMessage message) {
// Custom URL handling logic
String url = PushBundleDataProvider.getLink(message.toBundle());
if (url != null && url.startsWith("myapp://")) {
// Handle custom deep link
handleDeepLink(url);
} else {
super.startActivityForPushMessage(message);
}
}
Important Notes:
- Your extension class must be public and have a public no-argument constructor
- Application will crash on startup if these requirements are not met
- onMessageReceived runs on a background thread - use getApplicationContext safely
- startActivityForPushMessage runs on the main thread
- Returning
truefrom onMessageReceived suppresses notification display - Only one NotificationServiceExtension can be registered per application
See also
Functions
PendingIntent fires.