1page.title=Controlling Your App’s Volume and Playback
2parent.title=Managing Audio Playback
3parent.link=index.html
4
5trainingnavtop=true
6next.title=Managing Audio Focus
7next.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="#IdentifyStream">Identify Which Audio Stream to Use</a></li>
18  <li><a href="#HardwareVolumeKeys">Use Hardware Volume Keys to Control Your App’s Audio
19Volume</a></li>
20  <li><a href="#PlaybackControls">Use Hardware Playback Control Keys to Control Your App’s Audio
21Playback</a></li>
22</ol>
23
24<h2>You should also read</h2>
25<ul>
26  <li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li>
27</ul>
28
29</div>
30</div>
31
32
33
34<p>A good user experience is a predictable one. If your app plays media it’s important that your
35users can control the volume of your app using the hardware or software volume controls of their
36device, bluetooth headset, or headphones.</p>
37
38<p>Similarly, where appropriate and available, the play, stop, pause, skip, and previous media
39playback keys should perform their respective actions on the audio stream used by your app.</p>
40
41
42<h2 id="IdentifyStream">Identify Which Audio Stream to Use</h2>
43
44<p>The first step to creating a predictable audio experience is understanding which audio stream
45your app will use.</p>
46
47<p>Android maintains a separate audio stream for playing music, alarms, notifications, the incoming
48call ringer, system sounds, in-call volume, and DTMF tones. This is done primarily to allow users to
49control the volume of each stream independently.</p>
50
51<p>Most of these streams are restricted to system events, so unless your app is a replacement alarm
52clock, you’ll almost certainly be playing your audio using the {@link
53android.media.AudioManager#STREAM_MUSIC} stream.</p>
54
55
56<h2 id="HardwareVolumeKeys">Use Hardware Volume Keys to Control Your App’s Audio Volume</h2>
57
58<p>By default, pressing the volume controls modify the volume of the active audio stream. If your
59app isn't currently playing anything, hitting the volume keys adjusts the ringer volume.<p>
60
61<p>If you've got a game or music app, then chances are good that when the user hits the volume keys
62they want to control the volume of the game or music, even if they’re currently between songs or
63there’s no music in the current game location.</p>
64
65<p>You may be tempted to try and listen for volume key presses and modify the volume of your
66audio stream that way. Resist the urge. Android provides the handy {@link
67android.app.Activity#setVolumeControlStream setVolumeControlStream()} method to direct volume key
68presses to the audio stream you specify.<p>
69
70<p>Having identified the audio stream your application
71will be using, you should set it as the volume stream target. You should make this call early in
72your app’s lifecycle&mdash;because you only need to call it once during the activity lifecycle, you
73should typically call it within the {@code onCreate()} method (of the {@link
74android.app.Activity} or {@link android.app.Fragment} that controls
75your media). This ensures that whenever your app is visible, the
76volume controls function as the user expects.<p>
77
78<pre>
79setVolumeControlStream(AudioManager.STREAM_MUSIC);
80</pre>
81
82
83<p>From this point onwards, pressing the volume keys on the device affect the audio stream you
84specify (in this case “music”) whenever the target activity or fragment is visible.</p>
85
86
87<h2 id="PlaybackControls">Use Hardware Playback Control Keys to Control Your App’s Audio
88Playback</h2>
89
90<p>Media playback buttons such as play, pause, stop, skip, and previous are available on some
91handsets and many connected or wireless headsets. Whenever a user presses one of these hardware
92keys, the system broadcasts an intent with the {@link android.content.Intent#ACTION_MEDIA_BUTTON}
93action.</p>
94
95<p>To respond to media button clicks, you need to register a {@link
96android.content.BroadcastReceiver} in your manifest that listens for this action broadcast as shown
97below.</p>
98
99<pre>
100&lt;receiver android:name=".RemoteControlReceiver">
101    &lt;intent-filter>
102        &lt;action android:name="android.intent.action.MEDIA_BUTTON" />
103    &lt;/intent-filter>
104&lt;/receiver>
105</pre>
106
107<p>The receiver implementation itself needs to extract which key was pressed to cause the broadcast.
108The {@link android.content.Intent} includes this under the {@link
109android.content.Intent#EXTRA_KEY_EVENT} key, while the {@link android.view.KeyEvent} class includes
110a list {@code KEYCODE_MEDIA_*} static constants that represents each of the possible media
111buttons, such as {@link android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE} and {@link
112android.view.KeyEvent#KEYCODE_MEDIA_NEXT}.</p>
113
114<p>The following snippet shows how to extract the media button pressed and affects the media playback accordingly.</p>
115
116<pre>
117public class RemoteControlReceiver extends BroadcastReceiver {
118    &#64;Override
119    public void onReceive(Context context, Intent intent) {
120        if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
121            KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
122            if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) {
123                // Handle key press.
124            }
125        }
126    }
127}
128</pre>
129
130<p>Because multiple applications might want to listen for media button presses, you must
131also programmatically control when your app should receive media button press events.</p>
132
133<p>The following code can be used within your app to register and de-register your media button
134event receiver using the {@link android.media.AudioManager}. When registered, your broadcast
135receiver is the exclusive receiver of all media button broadcasts.<p>
136
137<pre>
138AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
139...
140
141// Start listening for button presses
142am.registerMediaButtonEventReceiver(RemoteControlReceiver);
143...
144
145// Stop listening for button presses
146am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
147</pre>
148
149<p>Typically, apps should unregister most of their receivers whenever they become inactive or
150invisible (such as during the {@link android.app.Activity#onStop onStop()} callback). However, it’s
151not that simple for media playback apps&mdash;in fact, responding to media playback buttons is most
152important when your application isn’t visible and therefore can’t be controlled by the on-screen
153UI.</p>
154
155<p>A better approach is to register and unregister the media button event receiver when your
156application gains and loses the audio focus. This is covered in detail in the next lesson.</p>
157