HorizonServiceConnectionApplication.getVersion()Application.launchOtherApp()startAppDownload(), cancelAppDownload(), and installAppUpdateAndRelaunch()application project in Android Studio. Replace the APPLICATION_ID placeholder in MainActivity.kt with your own application ID from the Meta Developer Dashboard. Build the project and deploy it to your Meta Quest device via ADB. For complete build instructions and version requirements, see the sample’s README.ViewModel managing SDK interactions.| File | What it demonstrates | Key concepts |
|---|---|---|
MainActivity.kt | SDK initialization and UI entry point | HorizonServiceConnection.connect() pattern, Compose setup, state collection with collectAsStateWithLifecycle() |
ApplicationViewModel.kt | Application API usage, state management | Application() instantiation, coroutine-based SDK calls on Dispatchers.IO, StateFlow with data class UiState pattern |
ApplicationViewModelTest.kt | Unit testing ViewModel state | Testing state defaults and immutability with data class copy() |
app/build.gradle.kts | SDK integration and dependencies | Core and application module dependencies, Compose BOM configuration |
MainActivity.onCreate() before setting up the Compose UI. The HorizonServiceConnection.connect() method takes three parameters: your application ID, the application context, and a coroutine scope (typically lifecycleScope). This initialization pattern is shared across all Horizon Platform SDK samples.ApplicationViewModel defines an executeAction function that wraps SDK calls with standardized loading and error handling. This pattern eliminates repetitive try/catch blocks and state management code across all five API methods. The wrapper sets isLoading = true, executes the SDK call on Dispatchers.IO, captures the JSON result or error message, and updates the UI state accordingly.executeAction() method in ApplicationViewModel.kt.launchOtherApp() method demonstrates the options pattern used throughout the Horizon Platform SDK. The sample uses ApplicationOptions.builder() to configure a deeplink message and destination API name, then calls .build() to create the immutable options object.launchOtherApp() method in ApplicationViewModel.kt.MutableStateFlow<ApplicationUiState> to manage UI state and exposes it as an immutable StateFlow. The Compose UI collects this flow with collectAsStateWithLifecycle(), ensuring state updates survive configuration changes and automatically cancel collection when the lifecycle stops. All SDK calls launch in viewModelScope on Dispatchers.IO to keep the main thread responsive.launchOtherApp().catch(Exception) block with targeted handlers for different failure modes.