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—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<receiver android:name=".RemoteControlReceiver"> 101 <intent-filter> 102 <action android:name="android.intent.action.MEDIA_BUTTON" /> 103 </intent-filter> 104</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 @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—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