This guide helps you implement background audio playback, system media controls, and Dolby Atmos spatial audio in your Android app running on Meta Horizon OS. By the end, your app will be able to continue audio playback in the background and provide users with familiar media controls.
Prerequisites
Library
Purpose
androidx.media3:media3-session
Media session management
androidx.media3:media3-exoplayer
Media playback engine
androidx.media3:media3-ui
Media UI components (optional)
Background audio
The background audio feature on Meta Horizon OS allows Android apps to continue playing audio while they’re not in the foreground. With background audio, users can stream music, listen to podcasts, or enjoy audiobooks while using other apps.
Add the required permissions and service declaration to your AndroidManifest.xml. See the Media3 MediaSession Guide for complete service configuration.
Implementation
To implement background audio in your Android app, use the standard Android media APIs:
MediaSession: Enables your app to communicate playback state and metadata to the system for media controls and notifications.
MediaSessionService: Runs as a foreground service to maintain audio playback in the background.
MediaStyle notifications: Provides media controls in the notification area.
These components work together: the service maintains playback, the session communicates state to the system, and notifications provide user-facing controls.
For complete implementation details, refer to the official Android documentation:
Once background playback is working, you can add system media controls.
Media playback controls
When a 2D app with audio is in the background on Meta Horizon OS, media playback controls become available. These controls work similarly to keyboard media controls on a PC. You can play, pause, skip tracks, and adjust volume without bringing the app back into focus.
Implementation
Implement media playback controls using the MediaSession API with callbacks for play, pause, skip, and other transport controls:
val player = ExoPlayer.Builder(context).build()
val mediaSession = MediaSession.Builder(context, player)
.setCallback(object : MediaSession.Callback {})
.build()
Media3’s MediaSession automatically handles media buttons and transport controls when you provide a Callback.
For complete implementation details, see the official Android Media3 documentation:
Meta Horizon OS supports Dolby Atmos for Android apps, delivering an immersive audio experience with spatial sound.
Detect Dolby Atmos support
Check if the device supports Dolby Atmos spatial audio:
import android.media.MediaCodecList
fun checkAtmosSupported(): Boolean {
val codecList = MediaCodecList(MediaCodecList.ALL_CODECS)
val atmosMimes = setOf("audio/eac3", "audio/eac3-joc")
return codecList.codecInfos.any { codecInfo ->
!codecInfo.isEncoder && codecInfo.supportedTypes.any { it in atmosMimes }
}
}
Supported formats
Meta Horizon OS supports the following Dolby audio formats:
Dolby Digital (AC-3) — audio/ac3
5.1 surround sound
Spatial audio: Not supported
2D playback: Supported
Dolby Digital Plus (E-AC-3) — audio/eac3
Enhanced surround sound with higher bitrates
Spatial audio: Supported (2D and 3D)
2D playback: Supported
Dolby Atmos (E-AC-3 JOC) — audio/eac3-joc
Object-based immersive audio with Joint Object Coding
Spatial audio: Supported (2D and 3D)
2D playback: Supported
Recommended for immersive experiences
Note: Dolby AC-4 (audio/ac4) is not currently supported on Meta Horizon OS.
Configuration
To prioritize Dolby Atmos playback, configure ExoPlayer’s track selector to prefer Atmos-capable formats:
val trackSelector = DefaultTrackSelector(context)
trackSelector.setParameters(
trackSelector.buildUponParameters()
.setPreferredAudioMimeTypes("audio/eac3-joc", "audio/eac3", "audio/ac3")
.build()
)
val player = ExoPlayer.Builder(context)
.setTrackSelector(trackSelector)
.build()
This configuration ensures ExoPlayer prioritizes Dolby Atmos (E-AC-3 JOC), then Dolby Digital Plus, then Dolby Digital when multiple audio tracks are available. For the best experience, ensure your media content includes Dolby Atmos audio streams.
To verify Dolby Atmos playback is working correctly:
Check your media player’s selected audio track format during playback.
Confirm the track uses one of the supported MIME types (audio/eac3-joc for Atmos).
Test with headphones to verify spatial audio positioning.
For media quality requirements and encoding specifications, see Media requirements.
Audio focus
Use Android’s AudioFocusRequest API to request audio focus before starting playback. Request AUDIOFOCUS_GAIN for exclusive audio playback or AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK for temporary playback that allows other audio to continue at reduced volume.
When using ExoPlayer, you can enable automatic audio focus handling:
val audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.AUDIO_CONTENT_TYPE_MUSIC)
.build()
val player = ExoPlayer.Builder(context)
.setAudioAttributes(audioAttributes, /* handleAudioFocus= */ true)
.build()
This automatically requests and abandons audio focus as playback starts and stops.