AudioFocusDemo
什么是AudioFocus
两个或更多Android应用可以同时播放同一输出流的音频。它对用户来说体验非常糟糕。为了避免每个音乐应用同时播放,Android引入了音频焦点的概念。一次只能有一个应用程序可以保持音频焦点。
准备
1.获取音频焦点
参数说明:
myAudioFocusChangeListener : 需要开发者定义 后面会写
AudioManager.STREAM_MUSIC :表述当前应用正在播放的音频类型
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT :durationHint 持续时间 (TRANSIENT 表示暂时持有)
int result = mAudioManager.requestAudioFocus(myAudioFocusChangeListener,
AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
2.AudioFocusChangeListener的实现,以下是一个编写参考
focusChange 是回调onAudioFocusChange 时发来的信号。假如当其他应用在该应用之后以GAIN_TRANSIENT的方式申请音频焦点,那么该应用就会收到AUDIOFOCUS_LOSS_TRANSIENT信号
class MyAudioFocusChangeListener implements AudioManager.OnAudioFocusChangeListener{
private int volume;
private int mPreviousState;
private boolean mShouldStart = true;
@Override
public void onAudioFocusChange(int focusChange) {
handlerAudioFocus(focusChange);
mPreviousState = focusChange;
}
private void handlerAudioFocus(int focusChange) {
if (focusChange != AudioManager.AUDIOFOCUS_GAIN){
volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
}
switch (focusChange){
case AudioManager.AUDIOFOCUS_GAIN:
Log.d(TAG, "handlerAudioFocus: AUDIOFOCUS_GAIN");
handlerAudioFocusGain(mPreviousState);
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
Log.d(TAG, "handlerAudioFocus: AUDIOFOCUS_LOSS_TRANSIENT");
mMediaPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS:
Log.d(TAG, "handlerAudioFocus: AUDIOFOCUS_LOSS");
mMediaPlayer.stop();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Log.d(TAG, "handlerAudioFocus: AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,volume/2,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
break;
}
}
private void handlerAudioFocusGain(int mPreviousState) {
switch (mPreviousState){
case AudioManager.AUDIOFOCUS_LOSS:
Log.d(TAG, "handlerAudioFocusGain: AUDIOFOCUS_LOSS");
initMediaPlayer();
mShouldStart = false;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
Log.d(TAG, "handlerAudioFocusGain: AUDIOFOCUS_LOSS_TRANSIENT");
if (mShouldStart) {
mMediaPlayer.start();
} else {
mShouldStart = true;
}
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Log.d(TAG, "handlerAudioFocusGain: AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
break;
}
}
}
3.获取焦点成功后,播放音乐或做其他操作
if(result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED){
mMediaPlayer.start();
}
4.丢弃焦点
mAudioManager.abandonAudioFocus(myAudioFocusChangeListener);
Demo参考
首先从service获取 AudioManager实例
AudioManager audioManager= (AudioManager)mContext.getSystemService(mContext.AUDIO_SERVICE)
初始化MediaPlayer ,用来测试也可以后台开音乐播放软件代替,例子中音频文件位于res同级目录下的assets下
private void initMediaPlayer() {
mMediaPlayer = new MediaPlayer();
AssetFileDescriptor fileDescriptor = null;
try {
fileDescriptor = getAssets().openFd("hello.mp3");
mMediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),fileDescriptor.getStartOffset(),fileDescriptor.getLength());
//mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}