1page.title=Managing Audio Focus 2parent.title=Managing Audio Playback 3parent.link=index.html 4 5trainingnavtop=true 6previous.title=Controlling Your App's Volume and Playback 7previous.link=volume-playback.html 8next.title=Dealing with Audio Output Hardware 9next.link=audio-output.html 10 11@jd:body 12 13 14<div id="tb-wrapper"> 15<div id="tb"> 16 17<h2>This lesson teaches you to</h2> 18<ol> 19 <li><a href="#RequestFocus">Request the Audio Focus</a></li> 20 <li><a href="#HandleFocusLoss">Handle the Loss of Audio Focus</a></li> 21 <li><a href="#DUCK">Duck!</a></li> 22</ol> 23 24 25<h2>You should also read</h2> 26<ul> 27 <li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li> 28</ul> 29 30</div> 31</div> 32 33 34<p>With multiple apps potentially playing audio it's important to think about how they should 35interact. To avoid every music app playing at the same time, Android uses audio focus to moderate 36audio playback—only apps that hold the audio focus should play audio.</p> 37 38<p>Before your app starts playing audio it should request—and receive—the audio focus. 39Likewise, it should know how to listen for a loss of audio focus and respond appropriately when that 40happens.</p> 41 42 43<h2 id="RequestFocus">Request the Audio Focus</h2> 44 45<p>Before your app starts playing any audio, it should hold the audio focus for the stream 46it will be using. This is done with a call to {@link android.media.AudioManager#requestAudioFocus 47requestAudioFocus()} which returns 48{@link android.media.AudioManager#AUDIOFOCUS_REQUEST_GRANTED} if your request is successful.</p> 49 50<p>You must specify which stream you're using and whether you expect to require transient or 51permanent audio focus. Request transient focus when you expect to play audio for only a short time 52(for example when playing navigation instructions). Request permanent audio focus when you 53plan to play audio for the foreseeable future (for example, when playing music).</p> 54 55<p>The following snippet requests permanent audio focus on the music audio stream. You should 56request the audio focus immediately before you begin playback, such as when the user presses 57play or the background music for the next game level begins.</p> 58 59<pre> 60AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE); 61... 62 63// Request audio focus for playback 64int result = am.requestAudioFocus(afChangeListener, 65 // Use the music stream. 66 AudioManager.STREAM_MUSIC, 67 // Request permanent focus. 68 AudioManager.AUDIOFOCUS_GAIN); 69 70if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 71 am.unregisterMediaButtonEventReceiver(RemoteControlReceiver); 72 // Start playback. 73} 74</pre> 75 76<p>Once you've finished playback be sure to call {@link 77android.media.AudioManager#abandonAudioFocus abandonAudioFocus()}. This notifies 78the system that you no longer require focus and unregisters the associated {@link 79android.media.AudioManager.OnAudioFocusChangeListener}. In the case of abandoning transient focus, 80this allows any interupted app to continue playback.</p> 81 82<pre> 83// Abandon audio focus when playback complete 84am.abandonAudioFocus(afChangeListener); 85</pre> 86 87<p>When requesting transient audio focus you have an additional option: whether or not you want to 88enable "ducking." Normally, when a well-behaved audio app loses audio focus it immediately 89silences its playback. By requesting a transient audio focus that allows ducking you tell other 90audio apps that it’s acceptable for them to keep playing, provided they lower their volume until the 91focus returns to them.</p> 92 93<pre> 94// Request audio focus for playback 95int result = am.requestAudioFocus(afChangeListener, 96 // Use the music stream. 97 AudioManager.STREAM_MUSIC, 98 // Request permanent focus. 99 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); 100 101if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 102 // Start playback. 103} 104</pre> 105 106<p>Ducking is particularly suitable for apps that use the audio stream intermittently, such as for 107audible driving directions.</p> 108 109<p>Whenever another app requests audio focus as described above, its choice between permanent and 110transient (with or without support for ducking) audio focus is received by the listener you 111registered when requesting focus.</p> 112 113 114<h2 id="HandleFocusLoss">Handle the Loss of Audio Focus</h2> 115 116<p>If your app can request audio focus, it follows that it will in turn lose that focus when another 117app requests it. How your app responds to a loss of audio focus depends on the manner of that 118loss.</p> 119 120<p>The {@link android.media.AudioManager.OnAudioFocusChangeListener#onAudioFocusChange 121onAudioFocusChange()} callback method of they audio focus change listener you registered when 122requesting audio focus receives a parameter that describes the focus change event. Specifically, 123the possible focus loss events mirror the focus request types from the previous 124section—permanent loss, transient loss, and transient with ducking permitted.</p> 125 126<p>Generally speaking, a transient (temporary) loss of audio focus should result in your app 127silencing it’s audio stream, but otherwise maintaining the same state. You should continue to 128monitor changes in audio focus and be prepared to resume playback where it was paused once you’ve 129regained the focus.</p> 130 131<p>If the audio focus loss is permanent, it’s assumed that another application is now being used to 132listen to audio and your app should effectively end itself. In practical terms, that means stopping 133playback, removing media button listeners—allowing the new audio player to exclusively handle 134those events—and abandoning your audio focus. At that point, you would expect a user action 135(pressing play in your app) to be required before you resume playing audio.</p> 136 137<p>In the following code snippet, we pause the playback or our media player object if the audio 138loss is transien and resume it when we have regained the focus. If the loss is permanent, it 139unregisters our media button event receiver and stops monitoring audio focus changes.<p> 140 141<pre> 142OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { 143 public void onAudioFocusChange(int focusChange) { 144 if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT 145 // Pause playback 146 } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 147 // Resume playback 148 } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 149 am.unregisterMediaButtonEventReceiver(RemoteControlReceiver); 150 am.abandonAudioFocus(afChangeListener); 151 // Stop playback 152 } 153 } 154}; 155</pre> 156 157<p>In the case of a transient loss of audio focus where ducking is permitted, rather than pausing 158playback, you can "duck" instead.</p> 159 160 161<h2 id="DUCK">Duck!</h2> 162 163<p>Ducking is the process of lowering your audio stream output volume to make transient audio from 164another app easier to hear without totally disrupting the audio from your own application.</p> 165 166<p>In the following code snippet lowers the volume on our media player object when we temporarily 167lose focus, then returns it to its previous level when we regain focus.</p> 168 169<pre> 170OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { 171 public void onAudioFocusChange(int focusChange) { 172 if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 173 // Lower the volume 174 } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 175 // Raise it back to normal 176 } 177 } 178}; 179</pre> 180 181<p>A loss of audio focus is the most important broadcast to react to, but not the only one. The 182system broadcasts a number of intents to alert you to changes in user’s audio experience. 183The next lesson demonstrates how to monitor them to improve the user’s overall experience.</p> 184