1 page.title=Managing Audio Focus 2 parent.title=Managing Audio Playback 3 parent.link=index.html 4 5 trainingnavtop=true 6 previous.title=Controlling Your App's Volume and Playback 7 previous.link=volume-playback.html 8 next.title=Dealing with Audio Output Hardware 9 next.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 35 interact. To avoid every music app playing at the same time, Android uses audio focus to moderate 36 audio 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. 39 Likewise, it should know how to listen for a loss of audio focus and respond appropriately when that 40 happens.</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 46 it will be using. This is done with a call to {@link android.media.AudioManager#requestAudioFocus 47 requestAudioFocus()} 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 51 permanent 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 53 plan 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 56 request the audio focus immediately before you begin playback, such as when the user presses 57 play or the background music for the next game level begins.</p> 58 59 <pre> 60 AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE); 61 ... 62 63 // Request audio focus for playback 64 int result = am.requestAudioFocus(afChangeListener, 65 // Use the music stream. 66 AudioManager.STREAM_MUSIC, 67 // Request permanent focus. 68 AudioManager.AUDIOFOCUS_GAIN); 69 70 if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 71 am.registerMediaButtonEventReceiver(RemoteControlReceiver); 72 // Start playback. 73 } 74 </pre> 75 76 <p>Once you've finished playback be sure to call {@link 77 android.media.AudioManager#abandonAudioFocus abandonAudioFocus()}. This notifies 78 the system that you no longer require focus and unregisters the associated {@link 79 android.media.AudioManager.OnAudioFocusChangeListener}. In the case of abandoning transient focus, 80 this allows any interupted app to continue playback.</p> 81 82 <pre> 83 // Abandon audio focus when playback complete 84 am.abandonAudioFocus(afChangeListener); 85 </pre> 86 87 <p>When requesting transient audio focus you have an additional option: whether or not you want to 88 enable "ducking." Normally, when a well-behaved audio app loses audio focus it immediately 89 silences its playback. By requesting a transient audio focus that allows ducking you tell other 90 audio apps that its acceptable for them to keep playing, provided they lower their volume until the 91 focus returns to them.</p> 92 93 <pre> 94 // Request audio focus for playback 95 int 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 101 if (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 107 audible driving directions.</p> 108 109 <p>Whenever another app requests audio focus as described above, its choice between permanent and 110 transient (with or without support for ducking) audio focus is received by the listener you 111 registered 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 117 app requests it. How your app responds to a loss of audio focus depends on the manner of that 118 loss.</p> 119 120 <p>The {@link android.media.AudioManager.OnAudioFocusChangeListener#onAudioFocusChange 121 onAudioFocusChange()} callback method of the audio focus change listener you registered when 122 requesting audio focus receives a parameter that describes the focus change event. Specifically, 123 the possible focus loss events mirror the focus request types from the previous 124 section—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 127 silencing its audio stream, but otherwise maintaining the same state. You should continue to 128 monitor changes in audio focus and be prepared to resume playback where it was paused once youve 129 regained the focus.</p> 130 131 <p>If the audio focus loss is permanent, its assumed that another application is now being used to 132 listen to audio and your app should effectively end itself. In practical terms, that means stopping 133 playback, removing media button listeners—allowing the new audio player to exclusively handle 134 those 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 138 loss is transient and resume it when we have regained the focus. If the loss is permanent, it 139 unregisters our media button event receiver and stops monitoring audio focus changes.<p> 140 141 <pre> 142 AudioManager.OnAudioFocusChangeListener afChangeListener = 143 new AudioManager.OnAudioFocusChangeListener() { 144 public void onAudioFocusChange(int focusChange) { 145 if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT) { 146 // Pause playback 147 } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 148 // Resume playback 149 } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 150 am.unregisterMediaButtonEventReceiver(RemoteControlReceiver); 151 am.abandonAudioFocus(afChangeListener); 152 // Stop playback 153 } 154 } 155 }; 156 </pre> 157 158 <p>In the case of a transient loss of audio focus where ducking is permitted, rather than pausing 159 playback, you can "duck" instead.</p> 160 161 162 <h2 id="DUCK">Duck!</h2> 163 164 <p>Ducking is the process of lowering your audio stream output volume to make transient audio from 165 another app easier to hear without totally disrupting the audio from your own application.</p> 166 167 <p>In the following code snippet lowers the volume on our media player object when we temporarily 168 lose focus, then returns it to its previous level when we regain focus.</p> 169 170 <pre> 171 OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { 172 public void onAudioFocusChange(int focusChange) { 173 if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { 174 // Lower the volume 175 } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 176 // Raise it back to normal 177 } 178 } 179 }; 180 </pre> 181 182 <p>A loss of audio focus is the most important broadcast to react to, but not the only one. The 183 system broadcasts a number of intents to alert you to changes in users audio experience. 184 The next lesson demonstrates how to monitor them to improve the users overall experience.</p> 185