Home | History | Annotate | Download | only in managing-audio
      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&mdash;only apps that hold the audio focus should play audio.</p>
     37 
     38 <p>Before your app starts playing audio it should request&mdash;and receive&mdash;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&mdash;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&mdash;allowing the new audio player to exclusively handle
    134 those events&mdash;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 OnAudioFocusChangeListener 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
    158 playback, 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
    164 another 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
    167 lose focus, then returns it to its previous level when we regain focus.</p>
    168 
    169 <pre>
    170 OnAudioFocusChangeListener 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
    182 system broadcasts a number of intents to alert you to changes in users audio experience.
    183 The next lesson demonstrates how to monitor them to improve the users overall experience.</p>
    184