Stealing Audio Focus from you

Taku Semba
Oct 19, 2018 · 3 min read

Since multiple apps can play audio to the same output stream simultaneously, the sound has to be controlled somehow so that apps can play sound nicely. To avoid the mess of playing audio from everywhere, Android introduces the idea of AudioFocus. Your app gains the AudioFocus to play sound, and if another app gains AudioFocus while your app plays sound, you might have to stop or duck the sound.

Audio Focus with ExoPlayer

Recently, ExoPlayer released the version of 2.9.0, which includes automatic AudioFocus handling. This automatically handles AudioFocus inside ExoPlayer, and you don’t have to care about AudioFocus handling much.

To let ExoPlayer manage AudioFocus automatically, you just pass an AudioAttributes to a player instance. How easy is it? It’ all done.

When you lose AudioFocus, there would be mainly three types of how you lose it, and ExoPlayer control the playback differently depends on the type.

AUDIOFOCUS_LOSS

This would be the situation where another app wants to play sound for a certain amount of time like a phone call, or VoIP call. For this, ExoPlayer stops the playback currently playing, and resume the playback after the app is done with playing audio.

AUDIOFOCUS_LOSS_TRANSIENT

This is when another app wants to play sound for a short amount of time, like an alarm. When this happens, ExoPlayer stops your playback as it does for AUDIOFOCUS_LOSS, and resume again after the temporally sound finished.

AUDIOFOCUS_LOSS_TRANSIENT_MAY_DUCK

This is also when another app wants to play sound for a short amount of time like AUDIOFOCUS_LOSS_TRANSIENT, but the difference is you are allowed to keep playing sound with lower volume. You could stop the sound, but it is ok to keep playing if you wanted. In terms of ExoPlayer, it lowers the volume by default but stops the sound if you set C.CONTENT_TYPE_SPEECH into setContentType()because when you play some speech it would be better to stop the sound rather than keep playing the speech.

Now What?

I understand how ExoPlayer behaves, but it is really too much trouble to check if your app behaves as you expected. You might don’t want to make a phone call or set an alarm just to see how your app reacts to it.

To make it easy, I created a library called AudioThief. It will gain and release AudioFocus for you, and you can see how your app reacts to lose and regain the AudioFocus.

First, it provides a foreground service called AudioFocusGainService, and you can simply start the service via adb command then the service will hold AudioFocus until you stop the service via adb command again.

start AudioFocusGainService

adb shell am startservice --ei AUDIO_REQUEST_KEY [audioRequestKey] your.package.name/com.takusemba.audiothief.AudioFocusGainService

stop AudioFocusGainService

adb shell am stopservice --ei AUDIO_REQUEST_KEY [audioRequestKey] your.package.name/com.takusemba.audiothief.AudioFocusGainService

For more information, please see README.md, and it would be super great if you give me a star for the repo.

Thank you.

Taku Semba

Written by

Android Engineer at AbemaTV Github: https://github.com/takusemba

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade