Skip to content

Commit b8ea1f9

Browse files
scottamainAndroid Git Automerger
authored andcommitted
am 4dc763c: Merge "doc change: Android U lessons for audio and battery" into ics-mr0
* commit '4dc763c700f79e33030e96eefabf8e5047cb9cb1': doc change: Android U lessons for audio and battery
2 parents 691fea7 + 4dc763c commit b8ea1f9

File tree

9 files changed

+952
-0
lines changed

9 files changed

+952
-0
lines changed
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
page.title=Managing Audio Focus
2+
parent.title=Managing Audio Playback and Focus
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.unregisterMediaButtonEventReceiver(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 it’s 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 they 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 it’s 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 you’ve
129+
regained the focus.</p>
130+
131+
<p>If the audio focus loss is permanent, it’s 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 transien 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 user’s audio experience.
183+
The next lesson demonstrates how to monitor them to improve the user’s overall experience.</p>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
page.title=Dealing with Audio Output Hardware
2+
parent.title=Managing Audio Playback and Focus
3+
parent.link=index.html
4+
5+
trainingnavtop=true
6+
previous.title=Managing Audio Focus
7+
previous.link=audio-focus.html
8+
9+
@jd:body
10+
11+
12+
<div id="tb-wrapper">
13+
<div id="tb">
14+
15+
<h2>This lesson teaches you to</h2>
16+
<ol>
17+
<li><a href="#CheckHardware">Check What Hardware is Being Used</a></li>
18+
<li><a href="#HandleChanges">Handle Changes in the Audio Output Hardware</a></li>
19+
</ol>
20+
21+
22+
<h2>You should also read</h2>
23+
<ul>
24+
<li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li>
25+
</ul>
26+
27+
28+
</div>
29+
</div>
30+
31+
<p>Users have a number of alternatives when it comes to enjoying the audio from their Android
32+
devices. Most devices have a built-in speaker, headphone jacks for wired headsets, and many also
33+
feature Bluetooth connectivity and support for A2DP audio. </p>
34+
35+
36+
<h2 id="CheckHardware">Check What Hardware is Being Used</h2>
37+
38+
<p>How your app behaves might be affected by which hardware its output is being routed to.</p>
39+
40+
<p>You can query the {@link android.media.AudioManager} to determine if the audio is currently
41+
being routed to the device speaker, wired headset, or attached Bluetooth device as shown in the
42+
following snippet:</p>
43+
44+
<pre>
45+
if (isBluetoothA2dpOn()) {
46+
// Adjust output for Bluetooth.
47+
} else if (isSpeakerphoneOn()) {
48+
// Adjust output for Speakerphone.
49+
} else if (isWiredHeadsetOn()) {
50+
// Adjust output for headsets
51+
} else {
52+
// If audio plays and noone can hear it, is it still playing?
53+
}
54+
</pre>
55+
56+
57+
<h2 id="HandleChanges">Handle Changes in the Audio Output Hardware</h2>
58+
59+
<p>When a headset is unplugged, or a Bluetooth device disconnected, the audio stream
60+
automatically reroutes to the built in speaker. If you listen to your music at as high a volume as I
61+
do, that can be a noisy surprise.</p>
62+
63+
<p>Luckily the system broadcasts an {@link android.media.AudioManager#ACTION_AUDIO_BECOMING_NOISY}
64+
intent when this happens. It’s good practice to register a {@link android.content.BroadcastReceiver}
65+
that listens for this intent whenever you’re playing audio. In the case of music players, users
66+
typically expect the playback to be paused&mdash;while for games you may choose to significantly
67+
lower the volume.</p>
68+
69+
<pre>
70+
private class NoisyAudioStreamReceiver extends BroadcastReceiver {
71+
&#64;Override
72+
public void onReceive(Context context, Intent intent) {
73+
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
74+
// Pause the playback
75+
}
76+
}
77+
}
78+
79+
private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
80+
81+
private void startPlayback() {
82+
registerReceiver(myNoisyAudioStreamReceiver(), intentFilter);
83+
}
84+
85+
private void stopPlayback() {
86+
unregisterReceiver(myNoisyAudioStreamReceiver);
87+
}
88+
</pre>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
page.title=Managing Audio Playback and Focus
2+
3+
trainingnavtop=true
4+
startpage=true
5+
next.title=Controlling Your App's Volume and Playback
6+
next.link=volume-playback.html
7+
8+
@jd:body
9+
10+
<div id="tb-wrapper">
11+
<div id="tb">
12+
13+
<h2>Dependencies and prerequisites</h2>
14+
<ul>
15+
<li>Android 2.0 (API level 5) or higher</li>
16+
<li>Experience with <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media
17+
Playback</a></li>
18+
</ul>
19+
20+
<h2>You should also read</h2>
21+
<ul>
22+
<li><a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a></li>
23+
</ul>
24+
25+
</div>
26+
</div>
27+
28+
29+
<p>If your app plays audio, it’s important that your users can control the audio in a predictable
30+
manner. To ensure a great user experience, it’s also important that your app manages the audio focus
31+
to ensure multiple apps aren’t playing audio at the same time.</p>
32+
33+
<p>After this class, you will be able to build apps that respond to hardware audio key presses,
34+
which request audio focus when playing audio, and which respond appropriately to changes in audio
35+
focus caused by the system or other applications.</p>
36+
37+
38+
39+
40+
<h2>Lessons</h2>
41+
42+
<!-- Create a list of the lessons in this class along with a short description of each lesson.
43+
These should be short and to the point. It should be clear from reading the summary whether someone
44+
will want to jump to a lesson or not.-->
45+
46+
<dl>
47+
<dt><b><a href="volume-playback.html">Controlling Your App’s Volume and
48+
Playback</a></b></dt>
49+
<dd>Learn how to ensure your users can control the volume of your app using the hardware or
50+
software volume controls and where available the play, stop, pause, skip, and previous media
51+
playback keys.</dd>
52+
53+
<dt><b><a href="audio-focus.html">Managing Audio Focus</a></b></dt>
54+
<dd>With multiple apps potentially playing audio it's important to think about how they should
55+
interact. To avoid every music app playing at the same time, Android uses audio focus to moderate
56+
audio playback. Learn how to request the audio focus, listen for a loss of audio focus, and how to
57+
respond when that happens.</dd>
58+
59+
<dt><b><a href="audio-output.html">Dealing with Audio Output Hardware</a></b></dt>
60+
<dd>Audio can be played from a number of sources. Learn how to find out where the audio is being
61+
played and how to handle a headset being disconnected during playback.</dd>
62+
</dl>

0 commit comments

Comments
 (0)