AudioFocus学习

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();
        }
    }

参考:Android Developers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值