getLaunchDetails(), including launch type and deeplink informationlogDeeplinkResult()launchIntentChanged() Flowapplicationlifecycle project in Android Studio. Before running the sample, replace the APPLICATION_ID property in MainActivity.kt with your application ID from the Meta Developer Portal. Build and deploy to your Quest device. For detailed build instructions and dependency setup, see the sample README.| File | What it demonstrates | Key concepts |
|---|---|---|
MainActivity.kt | SDK service connection and Compose UI host | HorizonServiceConnection.connect() called in onCreate() with application ID, context, and lifecycle scope |
ApplicationLifecycleViewModel.kt | Business logic and SDK API calls | Three methods demonstrating getLaunchDetails(), logDeeplinkResult(), and launchIntentChanged() Flow; all SDK calls on Dispatchers.IO |
ApplicationLifecycleUiState | Immutable UI state container | StateFlow pattern with loading, result, and error states |
launchIntentChanged() Flow. Success results appear in a white card below the buttons; errors appear in a red error card. A loading spinner displays while SDK calls are in progress.HorizonServiceConnection.connect() in onCreate() before setting up the Compose UI:HorizonServiceConnection.connect(
APPLICATION_ID,
this@MainActivity.applicationContext,
lifecycleScope,
)
onCreate() method in MainActivity.kt.ApplicationLifecycle API object requires no factory or dependency injection. The ViewModel creates it directly with a no-arg constructor:private val applicationLifecycle = ApplicationLifecycle()
val launchDetails = applicationLifecycle.getLaunchDetails()
val trackingId = launchDetails.trackingId
if (trackingId == null) { /* update error state */ return@launch }
applicationLifecycle.logDeeplinkResult(trackingId, LaunchResult.Unknown)
LaunchResult enum value based on the actual outcome. See ApplicationLifecycleViewModel.kt.getLaunchDetails(), which returns a single value, launchIntentChanged() returns a Flow for continuous monitoring. The sample uses .first() to await only the next emission, but production apps would typically collect the Flow continuously.logDeeplinkResult() to pass different LaunchResult enum values based on your app’s actual deeplink handling logic..first() call in listenForLaunchIntentChanged() with continuous Flow collection to handle multiple launch intent changes.