Android AudioManager处理两个播放器同时有声音,停止其中一个播放的问题

尽管某个时刻只有一个activity可以运行,Android却是一个多任务环境.这对使用音频的应用带来了特殊的挑战,因为只有一个音频输出而可能多个媒体都想用它.在Android2.2之前,没有内建的机制来处理这个问题,所以可能在某些情况下导致坏的用户体验.例如,当一个用户正在听音乐而另一个应用需要通知用户一些重要的事情时,用户可能由于音乐声音大而不能听的通知.从Android2.2开始,平台为应用提供了一个协商它们如何使用设备音频输出的途径,这个机制叫做音频焦点,AudioManager。
当你的应用需要输出像乐音和通知之类的音频时,你应该总是请求音频焦点.一旦应用具有了焦点,它就可以自由的使用音频输出.但它总是应该监听焦点的变化.如果被通知丢失焦点,它应该立即杀死声音或降低到静音水平(有一个标志表明应选择哪一个)并且仅当重新获得焦点后才恢复大声播放。
首先,注册一个焦点监听器OnAudioFocusChangeListener 。

private AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener = null;   
  //Build.VERSION.SDK_INT表示当前SDK的版本,Build.VERSION_CODES.ECLAIR_MR1为SDK 7版本 ,    
 //因为AudioManager.OnAudioFocusChangeListener在SDK8版本开始才有。    
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.ECLAIR_MR1){     
      mAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {   
        @Override
            public void onAudioFocusChange(int focusChange) {       
              if(focusChange == AudioManager.AUDIOFOCUS_LOSS){
                    //失去焦点之后的操作
                    if(isPlaying()){    
                           pause(); 
                           }
                }else if(focusChange == AudioManager.AUDIOFOCUS_GAIN){  
                //获得焦点之后的操作
                }   
                }   
    };      
}

要请求音频焦点,你必须从AudioManager mAudioMgr 调用requestAudioFocus(),如下所示:

private void requestAudioFocus() {  
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR_MR1){
        return;
    }
    if (mAudioMgr == null)
        mAudioMgr = (AudioManager) ApplicationEx.app.getSystemService(Context.AUDIO_SERVICE);
    if (mAudioMgr != null) {
        DLog.i(TAG, "Request audio focus");
        int ret = mAudioMgr.requestAudioFocus(mAudioFocusChangeListener,AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
        if (ret != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {               DLog.i(TAG, "request audio focus fail. " + ret);
        }
    }
}

放弃焦点

private void abandonAudioFocus() {
    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR_MR1){
        return;
    }
    if (mAudioMgr != null) {
        DLog.i(TAG, "Abandon audio focus");
        mAudioMgr.abandonAudioFocus(mAudioFocusChangeListener);
        mAudioMgr = null;
    }
}

参数focusChange告诉你音频焦点如何发生了变化,它可以是以上几种值(它们都是定义在AudioManager中的常量):
AUDIOFOCUS_GAIN:你已获得了音频焦点.

AUDIOFOCUS_LOSS:你已经丢失了音频焦点比较长的时间了.你必须停止所有的音频播放.因为预料到你可能很长时间也不能再获音频焦点,所以这里是清理你的资源的好地方.比如,你必须释放MediaPlayer.

AUDIOFOCUS_LOSS_TRANSIENT:你临时性的丢掉了音频焦点,很快就会重新获得.你必须停止所有的音频播放,但是可以保留你的资源,因为你可能很快就能重新获得焦点.

AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:你临时性的丢掉了音频焦点,但是你被允许继续以低音量播放,而不是完全停止.
转自:http://www.csdn123.com/html/blogs/20130507/10148.htm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Media Playback Android多媒体框架包涵了对播放多种通用媒体的类型的支持,所以你可以很容易的集成...
    VegetableAD阅读 4,394评论 0 0
  • Android 多媒体框架包含了支持播放的一系列常见多媒体类型,以此可以很容易地整合诸如音频、视频、图片到你的应用...
    LeaYw阅读 8,495评论 1 22
  • 因为系统中可能会有多个应用程序会播放音频,所以需要考虑他们之间该如何交互,为了避免多个应用程序同时播放音乐,...
    ZebraWei阅读 8,478评论 0 1
  • 这几天都很忙,所以断更了一天,后面几天还很迟才有时间写,今天趁这个空挡写一下吧,这样晚上就不用连睡觉也记着,今天...
    晴冰阅读 1,950评论 0 0
  • 首先 祝大家鸡年大吉 感觉大家一年总要跨好几次年——元旦、春节、生日,有的还要加上立春或冬至。用各种各样富有仪式感...
    墨之翎阅读 3,805评论 1 1