The Group Presence sample shows how to set and clear multiplayer presence information, manage destination and joinability state, and listen for join intents when other users attempt to join your session. It uses MVVM architecture with reactive state management using Kotlin Flows, targeting developers building multiplayer or social experiences on Meta Quest devices. View the sample source code on GitHub.
What you will learn
Initializing the Horizon Platform SDK using HorizonServiceConnection
Building and setting group presence options including deeplink messages, destinations, lobby IDs, and match session IDs
Updating presence state dynamically using individual setter methods
Listening for and handling join intents from other users using Kotlin Flows
Structuring a presence-aware Android application using MVVM with Compose UI
Clone the horizon-platform-sdk-samples repository and open the grouppresence project in Android Studio. Connect your Meta Quest device via USB, ensure Developer Mode is enabled, and run the app from the IDE. For complete build instructions and dependency configuration, see the sample README.
Explore the sample
File
What it demonstrates
Key concepts
MainActivity.kt
SDK initialization and Compose UI setup
HorizonServiceConnection.connect() with application ID, context, and coroutine scope
GroupPresenceUiState data class validation and copy behavior
Runtime behavior
When you run this sample, you see a screen titled Group Presence Sample with two sections of buttons and an output area. The Group Presence section contains Set and Clear buttons in the top row, with Set Destination and Set Joinable buttons in the second row. The Events section contains a Listen for Join Intent button. Each button triggers a Group Presence API call and displays the result or error message in the output area below.
Key concepts
SDK initialization
The sample initializes the Horizon Platform SDK once in MainActivity.onCreate():
val details = groupPresence.joinIntentReceived().first()
The joinIntentReceived() method returns a Flow that emits join intent details whenever another user attempts to join your session. The sample uses .first() to collect a single emission. For continuous monitoring, use collect() instead.
Extend the sample
Add persistent presence state: Store the current group presence configuration locally and restore it when the app restarts.
Implement multi-user join handling: Replace .first() with collect() to continuously monitor join intents from multiple users.
Combine with Rich Presence: Integrate the Rich Presence API to display additional context about the user’s current activity.