Android apps frequently play media, connect to Bluetooth peripherals, and react to network changes. Each capability uses dedicated APIs with specific permissions and lifecycle considerations.
Android supports playing audio from local files, raw resources, and streaming URLs. Manage audio focus so your app cooperates with other apps (calls, music players).
Play from raw resource
Kotlin — Play sound from res/raw/class SoundActivity : AppCompatActivity() {
private var mediaPlayer: MediaPlayer? = null
fun playNotificationSound() {
mediaPlayer?.release()
mediaPlayer = MediaPlayer.create(this, R.raw.notification_sound)
mediaPlayer?.setOnCompletionListener { mp ->
mp.release()
mediaPlayer = null
}
mediaPlayer?.start()
}
override fun onDestroy() {
mediaPlayer?.release()
mediaPlayer = null
super.onDestroy()
}
}
Audio focus (recommended for music apps)
Kotlin — Request audio focusprivate val audioManager by lazy {
getSystemService(Context.AUDIO_SERVICE) as AudioManager
}
private fun requestAudioFocus(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
.setOnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_LOSS -> pausePlayback()
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> pausePlayback()
AudioManager.AUDIOFOCUS_GAIN -> resumePlayback()
}
}
.build()
audioManager.requestAudioFocus(focusRequest) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
} else {
@Suppress("DEPRECATION")
audioManager.requestAudioFocus(
null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN
) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
}
}
Stream audio from URL
Kotlin — Stream MP3 from internetsuspend fun playStream(url: String) = withContext(Dispatchers.IO) {
val player = MediaPlayer().apply {
setAudioAttributes(
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
)
setDataSource(url)
prepareAsync()
setOnPreparedListener { it.start() }
}
}
2Video Playback
Video requires rendering frames to a SurfaceView, TextureView, or VideoView. For production apps, ExoPlayer (Media3) is recommended over raw MediaPlayer for streaming and adaptive bitrate.
Simple VideoView
XML — activity_video.xml<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="240dp" />
Kotlin — Play local or online videoclass VideoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_video)
val videoView = findViewById<VideoView>(R.id.videoView)
val mediaController = MediaController(this)
mediaController.setAnchorView(videoView)
videoView.setMediaController(mediaController)
// Local file
// val uri = Uri.parse("android.resource://$packageName/${R.raw.demo_video}")
// Online stream
val uri = Uri.parse("https://example.com/sample.mp4")
videoView.setVideoURI(uri)
videoView.setOnPreparedListener { it.start() }
}
override fun onPause() {
super.onPause()
findViewById<VideoView>(R.id.videoView).pause()
}
}
ExoPlayer (Media3 — recommended)
Kotlin — ExoPlayer setup// dependencies { implementation("androidx.media3:media3-exoplayer:1.2.1") }
class ExoPlayerActivity : AppCompatActivity() {
private var player: ExoPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_exo_player)
player = ExoPlayer.Builder(this).build().also { exoPlayer ->
binding.playerView.player = exoPlayer
val mediaItem = MediaItem.fromUri("https://example.com/sample.mp4")
exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.playWhenReady = true
}
}
override fun onStop() {
super.onStop()
player?.release()
player = null
}
}
Tip: Use ExoPlayer for HLS/DASH streaming, playlists, and subtitles. Use VideoView or MediaPlayer only for simple local or single-URL playback.
3MediaPlayer
MediaPlayer is the core Android class for audio and video playback. It supports local files, content URIs, and HTTP streams with playback controls.
Full MediaPlayer controller
Kotlin — MediaPlayerHelper.ktclass MediaPlayerHelper(private val context: Context) {
private var mediaPlayer: MediaPlayer? = null
fun play(filePath: String, onPrepared: (() -> Unit)? = null) {
release()
mediaPlayer = MediaPlayer().apply {
setAudioAttributes(
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
)
setDataSource(filePath)
setOnPreparedListener {
it.start()
onPrepared?.invoke()
}
setOnCompletionListener { release() }
prepareAsync()
}
}
fun pause() { mediaPlayer?.pause() }
fun resume() { mediaPlayer?.start() }
fun stop() { mediaPlayer?.stop(); release() }
fun seekTo(positionMs: Int) { mediaPlayer?.seekTo(positionMs) }
fun getDuration(): Int = mediaPlayer?.duration ?: 0
fun getCurrentPosition(): Int = mediaPlayer?.currentPosition ?: 0
fun isPlaying(): Boolean = mediaPlayer?.isPlaying == true
fun release() {
mediaPlayer?.release()
mediaPlayer = null
}
}
MediaPlayer states
Idle → Initialized → Prepared → Started ↔ Paused → Stopped → Released
↑ async prepare() or prepareAsync()
UI controls wired to MediaPlayer
Kotlin — Play / pause / seek barval helper = MediaPlayerHelper(this)
binding.btnPlay.setOnClickListener {
if (helper.isPlaying()) helper.pause()
else helper.resume()
}
binding.btnLoad.setOnClickListener {
helper.play("/storage/emulated/0/Music/song.mp3") {
binding.seekBar.max = helper.getDuration()
}
}
binding.seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) helper.seekTo(progress)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
// Update seek bar periodically while playing
lifecycleScope.launch {
while (isActive) {
if (helper.isPlaying()) {
binding.seekBar.progress = helper.getCurrentPosition()
}
delay(500)
}
}
4Bluetooth Basics
Bluetooth enables short-range wireless communication with headphones, speakers, wearables, and IoT devices. Android supports Classic Bluetooth and Bluetooth Low Energy (BLE).