This sample demonstrates how to send device notifications using the Horizon Platform SDK’s Notifications API. The code illustrates builder-based notification configuration, toast-only modes, and typed exception handling. View the sample source code on GitHub.
What you will learn
Configuring and sending device notifications using DeviceNotificationConfig.builder()
Creating toast-only notifications that display without persistence
Handling NotificationsException with structured error information
Managing async notification operations with coroutines and UI state
Structuring a notification-enabled app using MVVM architecture with Jetpack Compose
For detailed SDK version and toolchain requirements, see the sample’s README.
Get started
Clone or download the Horizon Platform SDK Samples repository and open the notifications project in Android Studio. The sample requires your application ID in MainActivity.kt before building. Connect your Quest device and run the app from Android Studio. For detailed build instructions, see the sample’s README.
When you run this sample, you see two action buttons: Device Notification and Toast Only. Tap Device Notification to send a notification with the title “Title from Notifications Sample App” and a corresponding message. Tap Toast Only to send an ephemeral toast-only notification. A loading indicator appears and both buttons become disabled during sending. On success, a card displays “Successfully sent notification.” On failure, an error-styled card displays the exception details including the request name, status code, and error message.
Key concepts
Builder pattern for notification config
The sample constructs notification configurations using the builder pattern:
val config = DeviceNotificationConfig.builder()
.withTitle("Title from Notifications Sample App")
.withMessage("Message from Notifications Sample App")
.build()
This pattern is standard across Horizon Platform SDK configuration objects.
Toast-only notifications
Toast-only notifications display briefly without persisting in the notification tray. The sample enables this mode by adding .withIsToastOnly(true) to the builder chain in the toastOnly() method.
Error handling with NotificationsException
The sample catches NotificationsException separately from generic exceptions, exposing structured error information with requestName, statusCode, and message properties for precise error diagnosis.
Async execution pattern
The executeAction() helper encapsulates the async notification pattern: set loading state, execute the SDK call on Dispatchers.IO, and update UI state on completion. The ViewModel exposes StateFlow<NotificationsUiState> that the Composable collects via collectAsStateWithLifecycle().
Extend the sample
Experiment with different notification titles and message content to test length limits and formatting.
Explore additional DeviceNotificationConfig builder options beyond the ones shown.
Try triggering notifications from a game loop or user interaction flow.