blob: 66649e8ac34b901316ba6b0c488c0a8b71ebf00e [file] [log] [blame]
Scott Main604e4ed2011-12-13 18:24:34 -08001page.title=Managing Audio Focus
Scott Main580f0142011-12-15 16:47:26 -08002parent.title=Managing Audio Playback
Scott Main604e4ed2011-12-13 18:24:34 -08003parent.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&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.
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 its 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&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
127silencing its 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 youve
129regained the focus.</p>
130
131<p>If the audio focus loss is permanent, its 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&mdash;allowing the new audio player to exclusively handle
134those 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
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 users audio experience.
183The next lesson demonstrates how to monitor them to improve the users overall experience.</p>