前段時間開發(fā)一款有音樂播放功能的app,當(dāng)然還是用到了MediaPlayer來實現(xiàn)音樂的播放。開發(fā)的過程中遇到了不少的問題,今天把這個媒體焦點的問題單獨拎出來講一講;
以前用微信的時候,就發(fā)現(xiàn)過一個問題,在播放微信語音的時候后臺的音樂會自動停掉,然后等語音播放完畢以后音樂又自動開始播放了,所以在我開發(fā)這個app的時候就注意到了這個問題--播放微信語音的時候我的app不會暫停播放音樂,好了,問題拋出來了,接下來就是解決問題了;
找了一些資料發(fā)現(xiàn)了音頻焦點這個概念,其實也是,手機上面可以安裝很多個有播放器功能的app,大家都播放音樂,假如沒有規(guī)則和機制來處理這個問題,那感覺就亂套了,所以從Android 2.2開始,Android平臺為應(yīng)用程序提供了一個方式來協(xié)商設(shè)備的音頻輸出,這個機制被稱為音頻焦點。廢話不多說,咱來看看這個機制;
首先來看請求焦點的偽代碼
AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
//請求媒體焦點
int result = mAudioManager.requestAudioFocus(audioFocusChangeListener,AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
//判斷請求焦點是否成功
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED){
//請求成功,這里你就可以開始播放了 (比如這時候在撥打電話,那請求是不成功的)
}
再來看看這個audioFocusChangeListener的代碼片段,我只是提了其中的三個狀態(tài),其余的可以到API里面去了解
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
//重新獲取焦點
case AudioManager.AUDIOFOCUS_GAIN:
//判斷是否需要重新播放音樂
if (needRestart) {
rePlay();
needRestart = false;
}
break;
//暫時失去焦點
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
//暫時失去焦點,暫停播放音樂(將needRestart設(shè)置為true)
if (pause()) {
needRestart = true;
}
break;
//時期焦點
case AudioManager.AUDIOFOCUS_LOSS:
//暫停播放音樂,不再繼續(xù)播放
pause();
break;
}
}
};
當(dāng)然在你不需要使用音頻的時候應(yīng)該取消焦點的占用
//取消注冊音頻競爭
if (mAudioManager != null && audioFocusChangeListener != null) {
mAudioManager.abandonAudioFocus(audioFocusChangeListener);
}
這只是最基本的一些代碼,其實在實際開發(fā)中還有需要注意的細節(jié),大家可以慢慢探索,比如你在監(jiān)聽到AudioManager.AUDIOFOCUS_LOSS暫停了音樂播放的時候,然后用戶操作繼續(xù)播放的時候,你需要重新獲取音頻焦點;
Android中只是定義這些規(guī)則,而且都期望(強烈鼓勵)遵守音頻焦點指南,但規(guī)則并不是系統(tǒng)強制執(zhí)行的。如果應(yīng)用程序失去音頻焦點后想要播放嘈雜的音樂,在系統(tǒng)中沒有什么會阻止他。然而,這樣可能會讓用戶有更糟糕的體驗,并可能卸載這運行不當(dāng)?shù)膽?yīng)用程序,所以希望廣大的開發(fā)者都能夠遵守這些規(guī)則,開發(fā)出有更好用戶體驗的app。