四,意外情况的控制。
在音频播放时候,容易遇到一些意外情况,这时候,我们就要处理这些意外情况,这时候,我们需要针对不同的意外情况进行处理。大概可以分成两种情况。
1,失去audio_focus的控制。
造成我们的播放器失去焦点的情况很多,主要是其他声音请求了焦点,例如说,其他音乐播放器开始播放音乐,突然来电,短息等。
以上的焦点失去,都可以用AudioManager.OnAudioFocusChangeListener中的回调来处理。先取得AudioManager
AudioManager audioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); 以下是进行申请焦点的两个方法, private int requestAudioFocus () { //Toast.makeText(mContext, "requestAudioFocus", Toast.LENGTH_SHORT).show(); return mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); } private int releaseAudioFocus () { //Toast.makeText(mContext, "releaseAudioFocus excuted", Toast.LENGTH_SHORT).show(); return mAudioManager.abandonAudioFocus(this); }
requestAudioFocus的调用时机是在start一个audio之前进行检查(mMediaPlayer.prepareAsync之前),一旦获取焦点失败,就不要去向下执行,不然当其他音频打断播放时候,我们不会收到及时的回调。注意此方法中,申请的焦点类型:AudioManager.STREAM_MUSIC
ReleaseAudioFocus的调用时机是,在我们的播放pause,stop,complete,error或者变成idle状态时候,都要去执行。为了及时释放焦点。
有一个小技巧,来判断是否获得了音乐播放的焦点,就是在我们应用取得焦点后,按音量键,此时调节的是音乐播放的音量,当我们暂停播放,调节音量是当前其他焦点类型的音量。如果我们在一开始播放未申请焦点,则音量调节不会对我们播放的音频生效。
那么失去焦点如何处理?我们在OnAudioFocusChangedListener中进行处理。
我的处理如下:
@Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_LOSS: releaseAudioFocus(); stop(); Dog.i(mContext, "Michael onAudioFocusChange", "AUDIOFOCUS_LOSS:" + focusChange); break; case AudioManager.AUDIOFOCUS_GAIN: mService.recoverVolume(); /*if (mService.getState() == MichaelService.State.PAUSED) { mService.resume(); }*/ Dog.i(mContext, "Michael onAudioFocusChange", "AUDIOFOCUS_GAIN:" + focusChange); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: pause(); Dog.i(mContext, "Michael onAudioFocusChange", "AUDIOFOCUS_LOSS_TRANSIENT:" + focusChange); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: mService.lowerVolume(); Dog.i(mContext, "Michael onAudioFocusChange", "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:" + focusChange); break; default: Dog.i(mContext, "Michael onAudioFocusChange", "default:" + focusChange); break; } }
值得注意的是:AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK这一类型,主要是针对类似于短信铃声这样的,当音乐播放时候,有短信,只会有du一声很短暂的声音,此时不需要我们去暂停音乐,只要减小音量即可。
2,插拔耳机的控制。
很明显,主要针对的是拔掉耳机。
说到拔掉耳机,很容易让人去监听拔掉耳机的系统广播,实际上不是这样的,我之前这么做过,出现了一个现象是:拔掉耳机后的一瞬间,能从外音能到一会儿音乐。如果,你监听这个广播再进行暂停,那你已经晚了。请恕我不将这个错误的广播公诸于众了。
我们要监听的是:AudioManager.ACTION_AUDIO_BECOMING_NOISY
系统广播监听很简单,去监听吧。注意在合适时候释放就好了。
按照以上指导思想,最近写成这样子了: