Android Live Notifications
Create and update dynamic notifications on Android Devices
Live Notifications
Android Live Notifications deliver live, dynamic content in notifications to enhance user engagement and app interactivity. This feature is similar to iOS's Live Activities but uses its own set of tools and APIs that enable similar functionalities. Android users must have push notifications enabled to receive a Live Notification.
Push versus Live Notifications
Live Notifications are an ongoing and constantly updating version of a push notification. The information stays on your screen in the same spot and keeps you informed with the latest.
Android widgets have provided real-time content directly on the home screen for some time. Widgets, in particular, are a staple of Android's Live Notification capability, offering customizable, at-a-glance views of app content without the need to open the app.
With OneSignal, you'll be able to send and update Live Notifications through the same Create Push Notification API but with additional parameters.
Requirements
- Your Android project is integrated with the latest version of the OneSignal SDK.
- Android users must have push notification permissions enabled.
Configuration
1. Configure Android Notification Service Extension
Create a new Notification Service Extension that implements the OneSignal INotificationServiceExtension
interface, refer to Android Notification Service Extension for detailed instructions. Within this class, override methods to intercept and alter notifications before they are displayed to the user.
Create a custom notification layout
Android provides instructions to create a custom notification layout. Sample code can be found on our Github or below. If you would like to contribute to our sample code, please fork, and not clone, the repository.
Use Notification Extender. Instead of the standard NotificationCompat.Builder
, use the Notification.setExtender
method to modify your notifications for Live Notifications This allows you to apply your custom layout and any additional modifications programmatically.
package com.onesignal.sample.android;
import com.onesignal.notifications.IActionButton;
import com.onesignal.notifications.IDisplayableMutableNotification;
import com.onesignal.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;
public class NotificationServiceExtension implements INotificationServiceExtension {
@Override
public void onNotificationReceived(INotificationReceivedEvent event) {
IDisplayableMutableNotification notification = event.getNotification();
if (notification.getActionButtons() != null) {
for (IActionButton button : notification.getActionButtons()) {
// you can modify your action buttons here
}
}
// this is an example of how to modify the notification by changing the background color to blue
notification.setExtender(builder -> builder.setColor(0xFF0000FF));
notification.setExtender(builder -> builder.setAutoCancel(false));
//If you need to perform an async action or stop the payload from being shown automatically,
//use event.preventDefault(). Using event.notification.display() will show this message again.
}
}
2. Modify Android Manifest
Sample code can be found on our Github or below. Be sure to update the android:value
on line 17 of your project.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:name=".MainApplication"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.OneSignalAndroidSample"
tools:targetApi="31">
<meta-data android:name="com.onesignal.NotificationServiceExtension"
android:value="com.onesignal.sample.android.NotificationServiceExtension" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
3. Create Live Notification Types
A Live Notification Type indicates which Live Notification to start.
Define notification identifiers
Notification identifiers indicate which notification to load and are used as keys in the Notification payload
private static final String PROGRESS_LIVE_NOTIFICATION = "progress";
Create notification channels
Channels determine the visual/audio behaviors of the notification and must have an identifier. To learn more about notification channels, refer to Android's documentation.
static final String PROGRESS_CHANNEL_ID = "progress_channel";
progressChannel = new NotificationChannel(PROGRESS_CHANNEL_ID, "Progress Live Notification", NotificationManager.IMPORTANCE_LOW);
progressChannel.setDescription("Shows the progress of a download");
notificationManager.createNotificationChannel(progressChannel);
Design a Live Notification
Live Notifications are most valuable when they present time-sensitive and dynamic information that users would otherwise go into the app to obtain.
int currentProgress = liveNotificationUpdates
.getInt("current_progress");
builder = new NotificationCompat.Builder(context, PROGRESS_CHANNEL_ID)
.setContentTitle("Progress Live Notification")
.setContentText("It's working...")
.setSmallIcon(android.R.drawable.ic_media_play)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), android.R.drawable.ic_dialog_info))
.setOngoing(true)
.setOnlyAlertOnce(true)
.setProgress(100, currentProgress, false);
notificationManager.notify(PROGRESS_LIVE_NOTIFICATION, 1, builder.build());
It's important to consider:
- Duration Live Notification will live in the notification center
- Outcomes you're trying to achieve and what information is most important to display
- Simple in design so users are not overwhelmed
A Live Notification can have:
- Small icon & accent color
- Large icon & accent color
- App name
- Big picture
- Notification sound
- Action buttons
4. Extract the Live Notification payload
The additional_data
property is optional, so build accordingly. If you send a regular push, nothing will happen because there is no Live Notification payload.
JSONObject liveNotificationPayload = Objects
.requireNonNull(notification.getAdditionalData())
.optJSONObject("live_notification");
Live Notification Schema
Property | Required | Description |
---|---|---|
key | Yes | Used to load the correct notification UI. |
event | Yes | The action to perform on the Live Notification. |
event_attributes | No | Static data used to initialize the Live Notification; Self-defined schema that defines the data your notification needs. |
event_updates | No | Dynamic content of the Live Notification. Must conform to the ContentState interface defined within your app's Live Notification. |
Example payload
{
"key": "celtics-vs-lakers",
"event": "start",
"event_attributes": {
"homeTeam": "Celtics",
"awayTeam": "Lakers",
"game": "Finals Game 1"
},
"event_updates": {
"quarter": 1,
"homeScore": 0,
"awayScore": 0,
}
}
5. Respond to Live Notification events
Obtain the event type from the Payload
String liveNotificationEvent = liveNotificationPayload.getString("event");
Event types
There are three events that you must handle when implementing Live Notifications: start
, update
, and end
. The event your request contains determines which properties must be included in your request.
Event | Description | Required parameters |
---|---|---|
start | Start the Live Notification with static and dynamic content that you want to display. | event_attributes , event_updates |
update | Update the Live Notification with new dynamic content. | event_updates |
end | End the Live Notification. | None |
Usage
This is the Live Notification schema for our example.
{
"live_notification": {
"key": "string",
"event": "start | update | end",
"event_attributes": {
"widget_attribute": "string"
},
"event_updates": {
"widget_content_state": "string"
}
}
}
Start Live Notification
This is the first step in sending Live Notifications to your customers.
- Set
event_attributes
to initialize the static data for the Live Notification with. This data will not change during the lifetime of the Live Notification. - Set
event_updates
data to initialize the dynamic data for the Live Notification. This is the data that can and will change during the lifetime of the Live Notification. - A
collapse_id
determines which notification to update and enables us to emulate a "Live Activity" by updating the same notification instead of showing a new notification. Set a collapse ID that is unique to this Live Notification to ensure subsequent updates are reflected in the same notification.
Example cURL request
curl -X "POST" "https://api.onesignal.com/notifications" \
-H 'Authorization: BASIC <OS_REST_API_KEY>' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"app_id": "<APP_ID>",
"target_channel": "push",
"isAndroid": true,
"collapse_id": "13"
"data": {
"live_notification": {
"key": "progress",
"event": "start",
"event_attributes": {},
"event_updates": {
"current_progress": 0
}
}
},
"headings": {
"en": "Start"
},
"contents": {
"en": "Starting Live Notification"
},
"include_aliases": {
"external_id": ["EID1", "EID2"]
}
}'
Update Live Notification
You can update a Live Notification as many times as you like, so long as it's started first.
- Set
event_updates
data to initialize the dynamic data for the Live Notification. This is the data that can and will change during the lifetime of the Live Notification and informs what to update your Live Notification's content with.
Example cURL request
curl -X "POST" "https://api.onesignal.com/notifications" \
-H 'Authorization: BASIC <OS_REST_API_KEY>' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"app_id": "<APP_ID>",
"target_channel": "push",
"isAndroid": true,
"collapse_id": "13"
"data": {
"live_notification": {
"key": "progress",
"event": "update",
"event_attributes": {},
"event_updates": {
"current_progress": 80
}
}
},
"headings": {
"en": "Update"
},
"contents": {
"en": "Updating Live Notification"
},
"include_aliases": {
"external_id": ["EID1", "EID2"]
}
}'
End Live Notification
Example cURL request
curl -X "POST" "https://api.onesignal.com/notifications" \
-H 'Authorization: Basic <OS_REST_API_KEY>' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"app_id": "<APP_ID>",
"target_channel": "push",
"isAndroid": true,
"collapse_id": "13"
"data": {
"live_notification": {
"key": "progress",
"event": "dismiss"
}
},
"headings": {
"en": "Dismissing"
},
"contents": {
"en": "Dismissing Live Notification"
},
"include_aliases": {
"external_id": ["EID1", "EID2"]
}
}'
Recommended
Prevent Auto-dismissal of Notifications
To keep a notification visible even after a user taps on it, call builder.setAutoCancel(false)
on your notification builder. This prevents the notification from being automatically dismissed, allowing it to stay in the notification tray until explicitly removed by the user or the app.
Updated 16 days ago