This guide provides a comprehensive walkthrough for implementing and customizing push notifications using the Reteno SDK for Android.
Table of Contents
- Customize default notification channel
- Deeplinks
- Push notification events
- Handling custom data
- Image carousel
- Push subscription status
- Custom push notifications
- Migrate from legacy notification events
Customize default notification channel
By default, the Reteno SDK creates a notification channel with the following parameters:
- ID:
retenoId - Name:
General - Description: Marketing notifications, news, app updates
- Importance:
IMPORTANCE_DEFAULT - Lights: disabled
- Vibration: disabled
- Lockscreen visibility: visible
- Bypass DND: false
- Show badge: true
To customize the default notification channel, use the defaultNotificationChannelConfig builder parameter during SDK initialization:
Note: The channel is created when the first push notification arrives in the app. After the channel is created, changes to these parameters are limited. Read more
Reteno.initWithConfig(
RetenoConfig.Builder()
.accessKey(...)
.defaultNotificationChannelConfig { builder ->
builder
.setName("Custom name")
.setDescription("Custom description")
.setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
.setLightColor(Color.RED)
.setLightsEnabled(true)
.setShowBadge(true)
.setVibrationEnabled(true)
.setVibrationPattern(longArrayOf())
.setSound(...)
}
.build()
)Reteno.initWithConfig(
new RetenoConfig.Builder()
.accessKey(...)
.defaultNotificationChannelConfig((builder) -> {
builder
.setName("Custom name")
.setDescription("Custom description")
.setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
.setLightColor(Color.RED)
.setLightsEnabled(true)
.setShowBadge(true)
.setVibrationEnabled(true)
.setVibrationPattern(longArrayOf())
.setSound(...);
return Unit.INSTANCE;
})
.build()
);User-visible channel name and description can be modified at any time during the application lifecycle. To edit those, use RetenoNotifications.updateDefaultNotificationChannel:
RetenoNotifications.updateDefaultNotificationChannel(
name = "New name",
description = "New description"
)RetenoNotifications.updateDefaultNotificationChannel(
"New name",
"New description"
);Deeplinks
The Reteno SDK optimizes the user experience by attempting to open deep links directly within your app, bypassing the browser's app-selection step.
- Behavior: If the app can handle the URL, it opens immediately. If not, it falls back to the system web browser.
- Android 12+ compatibility: Ensure your app complies with web intent resolution changes. Read more
- Setup: You must configure the appropriate Intent Filters in your
AndroidManifest.xml. Read more
Push notification events
Push received
To start listening for receive events:
RetenoNotifications.received.addListener { bundle ->
}RetenoNotifications.getReceived().addListener(bundle -> {
});To stop listening for receive events:
val myListener = Procedure<Bundle> {
//...
}
RetenoNotifications.received.removeListener(myListener);Procedure<Bundle> myListener = bundle -> {
//...
};
RetenoNotifications.getReceived().removeListener(myListener);Bundle contains all push notification information from Firebase.
Push clicked
To start listening for click events:
RetenoNotifications.click.addListener { bundle ->
}RetenoNotifications.getClick().addListener(bundle -> {
});To stop listening for click events:
val myListener = Procedure<Bundle> {
//...
}
RetenoNotifications.click.removeListener(myListener);Procedure<Bundle> myListener = bundle -> {
//...
};
RetenoNotifications.getClick().removeListener(myListener);Bundle contains all push notification information from Firebase.
Push swiped from notification tray
To start listening for close events:
RetenoNotifications.close.addListener { bundle ->
}RetenoNotifications.getClose().addListener(bundle -> {
});To stop listening for close events:
val myListener = Procedure<Bundle> {
//...
}
RetenoNotifications.close.removeListener(myListener);Procedure<Bundle> myListener = bundle -> {
//...
};
RetenoNotifications.getClose().removeListener(myListener);Bundle contains all push notification information from Firebase.
Handling custom data
You can pass your custom data in push notifications using the Custom data box in the Reteno admin panel. You can handle this custom data payload in the Launcher activity or the activity that handles deeplinks in the onCreate or onNewIntent methods. Custom data is delivered via intent extras.
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
val customDataValue = intent?.extras?.getString("customDataKey")
}@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String customDataValue = intent.getExtras().getString("customDataKey");
}Alternatively, all custom data is also passed to all Push notification event listeners.
Note: If you send a push notification containing a link that your application cannot handle, the web browser will handle this link. In this case, the web browser handles the custom data payload. To retrieve custom data from such a push, check the next section.
Image carousel
In the Reteno admin dashboard, you may select up to 10 images to be sent with a push notification. On Android, the notification will be shown as a DecoratedCustomViewStyle. Images will be scaled to 500 × 250 px to satisfy Android OS limits. The carousel will flip images automatically with a 2500 ms interval.
Push subscription status
Your end-user may prohibit receiving pushes by disabling the Reteno notification channel or disabling notifications for your application in Android OS settings. In this case, the SDK will notify its servers to prevent sending push notifications to this specific device.
SDK checks notifications enabled status in these cases:
- On app resume
- On push received event
- On settings changed in Android OS Settings menu (starting from Android 9.0, using system broadcast)
Once status false is sent to the server, the backend won't send any push notifications to this device until the end-user re-enables the channel/notifications. Once the end-user re-enables the channel/notifications, the server will be notified and will send push notifications again.
Custom push notifications
As an app developer, you may want to send not only Reteno marketing push notifications to your user, but your own pushes. These may be push notifications related to your app-specific functionality, like chat, calendar events, incoming call notification, etc.
To start listening for custom push notifications:
RetenoNotifications.custom.addListener { bundle ->
}RetenoNotifications.getCustom().addListener(bundle -> {
});To stop listening for custom push notifications:
val myListener = Procedure<Bundle> {
//...
}
RetenoNotifications.custom.removeListener(myListener);Procedure<Bundle> myListener = bundle -> {
//...
};
RetenoNotifications.getCustom().removeListener(myListener);Bundle contains all push notification information from Firebase.
IMPORTANT
Don't send custom push notifications with a
notificationblock in the JSON body. Usedataonly. This will guarantee that theBroadcastReceiverreceives your data payload consistently.DON'T:
{ "to": "FCM_token", "notification": { "title": "Title_here", "body": "Body_here" } }DO:
{ "to": "FCM_token", "data": { "Name": "John", "Room": 4, "Building": 3 } }Don't send the following key in your
datapayload:es_interaction_id.DON'T:
{ "to": "FCM_token", "data": { "Name": "John", "es_interaction_id": 123 } }
If Android receivers were used to listen for push notification events, manifest conflicts can arise. They can be resolved in two ways:
Retaining legacy event receivers
If you do not want to migrate to new listeners yet, you should override meta-data manifest entries adding tools:node="replace". Receivers with <action> intent filter can be left intact.
<meta-data
android:name="com.reteno.Receiver.PushReceived"
android:value="com.your.package.CustomReceiverPushReceived"
tools:node="replace"/>Migrating to new receivers
You can migrate your old receivers to new listener approach using this table:
| Event | Metadata name | New receiver |
|---|---|---|
| Push received | com.reteno.Receiver.PushReceived | RetenoNotifications.received.addListener |
| Push clicked | com.reteno.Receiver.NotificationClicked | RetenoNotifications.click.addListener |
| Push swiped from notification tray | com.reteno.Receiver.NotificationDeleted | RetenoNotifications.close.addListener |
| Custom push received | Any receiver with <action android:name="com.reteno.custom-push" /> | RetenoNotifications.click.addListener |
