Develop

Rich Presence sample overview

Updated: May 8, 2026

Overview

This sample demonstrates how to set, clear, and query presence destinations using the Horizon Platform SDK’s Rich Presence API. Rich Presence is deprecated in favor of Group Presence, but the core API patterns shown here translate to the newer API. View the sample source code on GitHub.

What you will learn

  • Initializing the Horizon SDK with HorizonServiceConnection.connect()
  • Building presence options using the fluent builder pattern
  • Setting and clearing Rich Presence status
  • Retrieving and paginating through destination data
  • Structuring presence features using MVVM architecture with Kotlin coroutines

Requirements

  • Meta Quest device
  • Android development environment
  • Application ID configured in your Meta developer account
For detailed build prerequisites and SDK setup instructions, see the sample README.

Get started

Clone or download the Horizon Platform SDK samples repository from GitHub. Open the richpresence/ folder in Android Studio, configure your Application ID following the setup guide, and run the app on your Meta Quest device.

Explore the sample

FileWhat it demonstratesKey concepts
MainActivity.kt
SDK initialization and Compose UI
HorizonServiceConnection.connect(), collectAsStateWithLifecycle()
RichPresenceViewModel.kt
Business logic and state management
RichPresence() API, coroutine-based async calls, StateFlow
RichPresenceViewModelTest.kt
Unit testing UI state defaults
RichPresenceUiState data class verification
build.gradle.kts
Dependencies and SDK versions
Horizon SDK artifacts, Compose configuration

Runtime behavior

When you launch the app, you see three buttons: Set Rich Presence, Clear Rich Presence, and Get Destinations. Tapping Set Rich Presence configures presence with hardcoded values and displays a success message. Clear Rich Presence removes the presence state. Get Destinations retrieves a paginated list of available destinations and displays the count and JSON representation of each. During any operation, a loading indicator appears and all buttons disable until the operation completes.

Key concepts

Builder pattern for presence options

The sample constructs RichPresenceOptions using a fluent builder API:
RichPresenceOptions.builder()
    .withApiName(apiName)
    .withDeeplinkMessageOverride(message)
    .withIsJoinable(joinable)
    .build()

Paged results for destinations

The getDestinations() method returns a paged result object. The sample fetches the initial page with fetchInitialPage().get(), then iterates through getFetchedPages() to access each page’s contents. Each destination object exposes a json property for serialization.

MVVM state management

The ViewModel exposes UI state through a read-only StateFlow while updating a private MutableStateFlow internally. All SDK calls run in viewModelScope.launch(Dispatchers.IO) with try/catch blocks updating error state on failure.

Extend the sample

  • Modify the hardcoded presence values in setPresence() to accept user input through text fields.
  • Add pagination controls to getDestinations() to fetch and display additional pages.
  • Migrate to the Group Presence API by exploring the grouppresence sample.