Advanced
The following guides cover advanced features and customization options available in the Actito SDK.
These topics are optional and can be adopted selectively based on your application’s requirements. You can safely skip any sections that are not relevant to your use case or implementation strategy.
Receiving Push Events
When using the Remote Notifications module, you can listen to a series of push events emitted by the SDK — including notification delivery, subscription updates, token changes, and live activity updates.
These events allow you to extend the default behavior — for example, logging notification activity, tracking delivery analytics, or triggering in-app actions when a notification is opened.
Once you’ve configured push notifications in your app, you can receive these events by implementing a custom broadcast receiver.
Using Intent Receiver
You can create a subclass of ActitoPushIntentReceiver to receive intents whenever the SDK emits push events.
class CustomPushIntentReceiver : ActitoPushIntentReceiver() {
override fun onSubscriptionChanged(context: Context, subscription: ActitoPushSubscription?) {
// Handle subscription updates
}
override fun onNotificationReceived(
context: Context,
notification: ActitoNotification,
deliveryMechanism: ActitoNotificationDeliveryMechanism
) {
// Handle incoming notification
}
override fun onNotificationOpened(context: Context, notification: ActitoNotification) {
// Handle notification opened by the user
}
override fun onActionOpened(
context: Context,
notification: ActitoNotification,
action: ActitoNotification.Action
) {
// Handle specific notification action
}
override fun onSystemNotificationReceived(context: Context, notification: ActitoSystemNotification) {
// Handle system notifications (e.g. internal SDK messages)
}
override fun onUnknownNotificationReceived(context: Context, notification: ActitoUnknownNotification) {
// Handle unrecognized notification formats
}
override fun onLiveActivityUpdate(context: Context, update: ActitoLiveActivityUpdate) {
// Handle updates to live activities
}
}
Then, register your receiver so that the SDK can forward events to it:
Actito.push().intentReceiver = CustomPushIntentReceiver::class.java
Finally, declare the intent receiver on your AndroidManifest.xml:
<receiver android:name=".CustomPushIntentReceiver"
android:exported="false" />
Push events
onSubscriptionChanged: Called when the device's push subscription changes.
override fun onSubscriptionChanged(context: Context, subscription: ActitoPushSubscription?) {
Log.i(TAG, "Subscription updated: ${subscription?.token}")
}
onNotificationReceived: Called when a push notification is received.
override fun onNotificationReceived(context: Context, notification: ActitoNotification, deliveryMechanism: ActitoNotificationDeliveryMechanism) {
Log.i(TAG, "Received notification: ${notification.id} via $deliveryMechanism")
}
onNotificationOpened: Called when a push notification is opened by the user.
override fun onNotificationOpened(context: Context, notification: ActitoNotification) {
Log.i(TAG, "Opened notification: ${notification.id}")
}
onActionOpened: Called when a push notification action is opened by the user.
override fun onActionOpened(context: Context, notification: ActitoNotification, action: ActitoNotification.Action) {
Log.i(TAG, "Opened action: ${action.label}")
}
onSystemNotificationReceived: Called when a custom system notification is received.
override fun onSystemNotificationReceived(context: Context, notification: ActitoSystemNotification) {
Log.i(TAG, "System notification received: ${notification.id}")
}
onUnknownNotificationReceived: Called when an unknown notification is received.
override fun onUnknownNotificationReceived(context: Context, notification: ActitoUnknownNotification) {
Log.i(TAG, "Unknown notification received: ${notification.messageId}")
}
onLiveActivityUpdate: Called when a live activity update is received.
override fun onLiveActivityUpdate(context: Context, update: ActitoLiveActivityUpdate) {
Log.i(TAG, "Live activity update: ${update.activity}")
}
Live Activities
Live Activities let you emulate the iOS Live Activity experience on Android by displaying real-time, glanceable updates from your app — such as order deliveries, ride progress, sports scores, or timers — without requiring users to open the app.
The Actito SDK provides an API that allows you to register and manage these activities, enabling your app to receive remote updates from Actito campaigns or API integrations. You can use this mechanism to power any kind of custom UI — such as a notification, widget, or in-app view — giving you complete control over how Live Activity updates are displayed to the user.
This guide explains how to register and manage Live Activities through the Actito SDK.
Registering an activity
To start receiving remote updates for a Live Activity, register it with Actito by calling registerLiveActivity().
An activityId uniquely identifies the ongoing activity, while the optional topics parameter can be used for grouping or targeting activities.
Actito.push().registerLiveActivity("order-tracker", listOf("sample"))
Ending an activity
When the Live Activity completes — either because the process ends or the user dismisses it — your app must explicitly notify Actito by calling endLiveActivity().
This ensures that Actito stops sending updates to the ended activity and accurately tracks lifecycle metrics.
Actito.push().endLiveActivity("order-tracker")
Listening to activity updates
While iOS automatically updates the associated UI, we must do this manually since there is no dedicated OS mechanism.
Once you have configured the ActitoPushIntentReceiver to your instance, you can listen to the onLiveActivityUpdate() event. At this point, you can act on the update and adjust your UI accordingly.
class CustomPushReceiver : ActitoPushIntentReceiver() {
override fun onLiveActivityUpdate(context: Context, update: ActitoLiveActivityUpdate) {
// update your UI
}
}
Listening to token changes
Sometimes, Firebase will refresh the push token associated with your device. At this point, you must re-register any ongoing Live Activities to continue receiving updates.
class CustomPushReceiver : ActitoPushIntentReceiver() {
override fun onSubscriptionChanged(context: Context, subscription: ActitoPushSubscription?) {
// register the ongoing activities again
}
}
Notification lifecycle
When using the Push UI module to present notifications and actions, you can listen to a series of lifecycle events emitted during the notification presentation process. In more advanced implementations, these events can be leveraged to execute additional logic — such as tracking analytics, updating application state, or triggering custom navigation behaviors.
To do this, make your Activity (or a dedicated handler) implement the ActitoPushUI.NotificationLifecycleListener. This listener provides hooks for key points in the notification lifecycle — from presentation to action execution.
class MainActivity : AppCompatActivity(), ActitoPushUI.NotificationLifecycleListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// more code ...
Actito.pushUI().addLifecycleListener(this)
}
override fun onDestroy() {
super.onDestroy()
// more code ...
Actito.pushUI().removeLifecycleListener(this)
}
override fun onNotificationWillPresent(notification: ActitoNotification) { }
override fun onNotificationPresented(notification: ActitoNotification) { }
override fun onNotificationFinishedPresenting(notification: ActitoNotification) { }
override fun onNotificationFailedToPresent(notification: ActitoNotification) { }
override fun onNotificationUrlClicked(notification: ActitoNotification, uri: Uri) { }
override fun onActionWillExecute(notification: ActitoNotification, action: ActitoNotification.Action) { }
override fun onActionExecuted(notification: ActitoNotification, action: ActitoNotification.Action) { }
override fun onActionFailedToExecute(
notification: ActitoNotification,
action: ActitoNotification.Action,
error: Exception?
) { }
override fun onCustomActionReceived(
notification: ActitoNotification,
action: ActitoNotification.Action,
uri: Uri,
) { }
}
Notification Presentation Events
These methods notify you of each stage in a notification’s presentation lifecycle:
onNotificationWillPresent: Called immediately before the notification is displayed.
override fun onNotificationWillPresent(notification: ActitoNotification) {
Log.i(TAG, "About to present notification: ${notification.id}")
}
onNotificationPresented: Called right after the notification is presented.
override fun onNotificationPresented(notification: ActitoNotification) {
Log.i(TAG, "Presented notification: ${notification.id}")
}
onNotificationFinishedPresenting: Called when the notification UI has been dismissed or closed.
override fun onNotificationFinishedPresenting(notification: ActitoNotification) {
Log.i(TAG, "Notification finished presenting: ${notification.id}")
}
onNotificationFailedToPresent: Called if an error occurs during presentation.
override fun onNotificationFailedToPresent(notification: ActitoNotification) {
Log.i(TAG, "Failed to present notification: ${notification.id}")
}
onNotificationUrlClicked: Called when the user taps a URL link inside the notification content.
override fun onNotificationUrlClicked(notification: ActitoNotification, uri: Uri) {
Log.i(TAG, "Clicked previously configured URL for HTML or Web Page notifications type: $uri")
}
Action Execution Events
These methods notify you of each stage in an action’s execution lifecycle:
onActionWillExecute: Called just before an action is performed.
override fun onActionWillExecute(notification: ActitoNotification, action: ActitoNotification.Action) {
Log.i(TAG, "Preparing to execute action: ${action.label}")
}
onActionExecuted: Called when the action has been successfully performed.
override fun onActionExecuted(notification: ActitoNotification, action: ActitoNotification.Action) {
Log.i(TAG, "Executed action: ${action.label}")
}
onActionFailedToExecute: Called when the SDK attempted to execute the action but encountered an error.
override fun onActionFailedToExecute(
notification: ActitoNotification,
action: ActitoNotification.Action,
error: Exception?
) {
Log.i(TAG, "Action failed: $error")
}
onCustomActionReceived: Gives you an opportunity to intercept and decide how to handle a custom action.
override fun onCustomActionReceived(
notification: ActitoNotification,
action: ActitoNotification.Action,
uri: Uri,
) {
Log.i(TAG, "Received a custom action to execute: ${action.label}")
}