处理音频焦点
虽然某个时刻只要一个activity能够运转,Android却是一个多任务环境.这对运用音频的运用带来了特别的应战,由于只要一个音频输出而或许多个媒体都想用它.在Android2.2之前,没有内建的机制来处理这个问题,所以或许在某些情况下导致坏的用户体会.例如,当一个用户正在听音乐而另一个运用需求告知用户一些重要的工作时,用户或许由于音乐声响大而不能听的告知.从Android2.2开端,渠道为运用供给了一个洽谈它们怎么运用设备音频输出的途径,这个机制叫做音频焦点.
当你的运用需求输出像乐音和告知之类的音频时,你应该总是恳求音频焦点.一旦运用具有了焦点,它就能够自在的运用音频输出.但它总是应该监听焦点的改动.假如被告知丢掉焦点,它应该当即杀死声响或降低到静音水平(有一个标志标明应挑选哪一个)而且仅当从头取得焦点后才康复大声播映.
将来的音频焦点是协作的.所以,运用被期望(并被强列鼓舞)恪守音频焦点的政策,可是却不是被体系强制的.假如一个运用在丢掉音频焦点后仍然想大声播映音乐,体系不会去阻挠它.可是用户却体会很坏而且很想把这鸟运用卸载.
要恳求音频焦点,你有必要从AudioManager调用requestAudioFocus(),如下所示:
[java]
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// 不能取得音频焦点
}
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// 不能取得音频焦点
}
requestAudioFocus()的第一个参数是一个AudioManager.OnAudioFocusChangeListener,它的onAudioFocusChange()办法在音频焦点发改动时被调用.因而,你也应该在你的service和activity上完成此接口.例如:
[java]
class MyService extends Service
implements AudioManager.OnAudioFocusChangeListener {
// ….
public void onAudioFocusChange(int focusChange) {
// Do something based on focus change…
}
}
class MyService extends Service
implements AudioManager.OnAudioFocusChangeListener {
// ….
public void onAudioFocusChange(int focusChange) {
// Do something based on focus change…
}
}
参数focusChange告知你音频焦点怎么发生了改动,它能够是以上几种值(它们都是界说在AudioManager中的常量):
AUDIOFOCUS_GAIN:你已取得了音频焦点.
AUDIOFOCUS_LOSS:你现已丢掉了音频焦点比较长的时刻了.你有必要中止一切的音频播映.由于意料到你或许很长时刻也不能再获音频焦点,所以这里是整理你的资源的好地方.比方,你有必要开释MediaPlayer.
AUDIOFOCUS_LOSS_TRANSIENT:你临时性的丢掉了音频焦点,很快就会从头取得.你有必要中止一切的音频播映,可是能够保存你的资源,由于你或许很快就能从头取得焦点.
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:你临时性的丢掉了音频焦点,可是你被答应持续以低音量播映,而不是彻底中止.
下面是一个比如:
[java]
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
if (mMediaPlayer == null) initMediaPlayer();
else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don’t release the media player because playback
// is likely to resume
if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but it’s ok to keep playing
// at an attenuated level
if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
break;
}
}
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
if (mMediaPlayer == null) initMediaPlayer();
else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don’t release the media player because playback