This article translated from: http://developer.android.com/training/managing-audio/audio-focus.html
It is vital to consider how to interact with multiple potential audio playback programs. To avoid simultaneous playback of each music player, Android uses audio focus to control audio playback. Only applications with audio focus can play audio.
Before your application starts playing the audio, it should request and receive the audio focus. In addition, it should know how to monitor the loss of audio focus and how to make the correct response when the audio focus is lost.
Request audio focus
Before the application starts playing any audio, it should have the audio focus of the audio stream it will use. Call requestaudiofocus () to obtain the audio focus. If the request is successful, audiofocus_request_granted is returned.
You must specify the audio stream you want to use, and the required audio focus is temporary and persistent. When you want to play only a short audio, you can request a temporary audio focus (such as playback navigation instructions ). When playing a predictable audio, you can request a persistent audio focus (for example, when playing a music ).
The following code snippet requests a persistent audio focus on a music audio stream. Before starting playing the video, you should immediately request the audio focus, for example, when you press the play button or before the next game level background music starts.
Audiomanager AM
= Mcontext. getsystemservice (context. audio_service );
...
// Request audio focus for playback
Int result = aM. requestaudiofocus (afchangelistener,
// Use the music stream.
Audiomanager. stream_music,
// Request permanent focus.
Audiomanager. audiofocus_gain );
If (result = audiomanager. audiofocus_request_granted ){
Am. unregistermediabuttoneventreceiver (remotecontrolpolicer );
// Start playback.
}
After playing the video, make sure to call the abandonaudiofocus () method. This method will notify the system that you no longer need the audio focus, and will cancel the registration associated with audiomanager. onaudiofocuschangelistener. If you discard the temporary audio focus, any interrupted application is allowed to continue playing.
// Abandon audio focus when playback complete
Am. abandonaudiofocus (afchangelistener );
When requesting a temporary audio focus, another option is available: whether to enable "avoidance ". Normally, a good audio application immediately disables playback when the audio focus is lost. By requesting temporary allowable avoidance of audio focus, other accessible audio applications are notified to remain in the playing state, but their volume is reduced until the audio focus is returned to them.
// Request audio focus for playback
Int result = aM. requestaudiofocus (afchangelistener,
// Use the music stream.
Audiomanager. stream_music,
// Request permanent focus.
Audiomanager. audiofocus_gain_transient_may_duck );
If (result = audiomanager. audiofocus_request_granted ){
// Start playback.
}
"Avoidance" is especially useful for applications that occasionally apply audio streams, such as voice driving navigation.
No matter when the application requests the audio focus type described above, it registers the listener to receive persistent or temporary audio focus (which cannot be avoided ).
Processing loss of audio focus
If your application can request the audio focus, it will lose the focus when another application requests the focus. How does your application respond to the loss dependency of the audio focus and manage the loss focus.
The onaudiofocuschange () callback method of the audio focus change listener you register receives a parameter that describes the focus change event. Specifically, possible focus loss events correspond to the type of request focus mentioned above-persistent loss, temporary loss, and temporary loss with avoidance allowed.
In general, temporary loss of audio focus will cause your application to silence its audio stream, but remain in the same status in other aspects. You should continue to monitor changes in the audio focus and prepare to resume paused audio stream playback when you obtain the focus again.
If the lost audio focus is persistent, it assumes that you are using another application to listen to the audio, and your application should be effectively ended. In practice, this means to stop playing and delete the media button listener-allow new audio players to handle these events-and discard your audio focus. Before resuming playing the audio, you will expect the user to perform the necessary operations (such as pressing the play button in the application ).
In the following code snippet, if a temporary audio focus is lost, we pause the playback or Media Player Object and resume it when getting the focus again. If persistent audio focus is lost, it removes the registration of our media button event and stops listening for audio focus changes.
Onaudiofocuschangelistener afchangelistener
= Newonaudiofocuschangelistener (){
Public void onaudiofocuschange (INT focuschange ){
If (focuschange = audiofocus_loss_transient
// Pause playback
} Else if (focuschange = audiomanager. audiofocus_gain ){
// Resume playback
} Else if (focuschange = audiomanager. audiofocus_loss ){
Am. unregistermediabuttoneventreceiver (remotecontrolpolicer );
Am. abandonaudiofocus (afchangelistener );
// Stop playback
}
}
};
When the audio focus is temporarily lost and you are allowed to avoid it, you can use "Withdraw" instead of "pause.
Avoidance
Avoidance is a process that reduces the volume of your temporary audio stream output, making the audio of another application easier to hear without obfuscation with the audio stream of your application.
The following code snippet will reduce the volume of the media play object when the focus is temporarily lost, and then return to the previous level when the focus is retrieved again.
Onaudiofocuschangelistener afchangelistener
= Newonaudiofocuschangelistener (){
Public void onaudiofocuschange (INT focuschange ){
If (focuschange = audiofocus_loss_transient_can_duck ){
// Lower the volume
} Else if (focuschange = audiomanager. audiofocus_gain ){
// Raise it back to normal
}
}
};
The loss of audio focus is the most important broadcast, but it is not the only one. The system broadcasts many intents to remind you to change the user's audio experience. The next lesson demonstrates how to monitor these broadcasts to improve the overall user experience.