- 場景:當(dāng)聽音樂并且在刷朋友圈或者微博的時候,我們想點擊一個視頻看,此時音樂會暫停只保留視頻播放,然后退出視頻后音樂又重新播放;
在Android2.2時引入了AudioFocus機(jī)制來對Audio資源的競爭進(jìn)行管理與協(xié)調(diào);需要Audio資源雙方都實現(xiàn)該機(jī)制才能完成當(dāng)一方失去或者得到焦點時,另一方能夠進(jìn)行反應(yīng):停止播放或者降低音量的效果;
- 獲取AudioManager實例:
AudioManager magager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
- 請求音頻的焦點
requestAudioFocus(AudioManager.OnAudioFocusChangeListener l,int streamType,int durationHint):
參數(shù)一:申請成功后對AudioFocus的監(jiān)聽;
參數(shù)二:音頻類型
STREAM_ALARM:手機(jī)鬧鈴,STREAM_MUSIC:手機(jī)音樂
STREAM_RING:電話鈴聲,STREAM_SYSTEAM:手機(jī)系統(tǒng)
STREAM_DTMF:音調(diào),STREAM_NOTIFICATION:系統(tǒng)提示
STREAM_VOICE_CALL:語音電話
參數(shù)三:
AudioManager.AUDIOFOCUS_GAIN:長時間獲得AudioFocus
AudioManager.AUDIOFOCUS_LOSS:
長時間失去了Audio Focus,需要停止Audio的播放,并且釋放Media資源。為了避免再次自動獲得AudioFocus而繼續(xù)播放,不然突然冒出來的聲音會讓用戶感覺莫名其妙,直接放棄AudioFocus,如果需要再次播放,用戶要在界面上點擊開始播放,才重新初始化Media,進(jìn)行播放。
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
暫時失去AudioFocus,并會很快再次獲得。必須停止Audio的播放,但是因為是暫時失去AudioFocus,可以不釋放Media資源;
AUDIOFOCUS_GAIN_TRANSIENT:暫時獲取焦點 適用于短暫的音頻
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:應(yīng)用跟其他應(yīng)用共用焦點但播放的時候其他音頻會降低音量
返回值:
AUDIOFOCUS_REQUEST_GRANTED:申請成功;
AUDIOFOCUS_REQUEST_FAILED:申請失?。?/p>
放棄音頻的焦點
abandonAudioFocus(AudioManager.OnAudioFocusChangeListenerl)AudioFocus被搶占與再次獲取的時序
Client通過requestAudioFocus()獲取AudioFocus,在獲得AudioFocus之后,開始播放Audio;
其它程序(Other App)也通過requestAudioFocus()獲取同類AudioStream的AudioFocus
Client失去了AudioFocus,在onAudioFocusChanged()中,根據(jù)focusChange的值,做相應(yīng)的處理(暫停or播放);
其它程序(Other App)獲取AudioFocus之后,開始播放Audio;
其它程序(Other App)使用Audio之后,通過abandonAudioFocus()歸還AudioFocus;
Client重新獲得了Audio Focus,可做進(jìn)一步的處理
- 示例:
//獲取AudioManager對象
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//注冊O(shè)nAudioFocusChangeListener監(jiān)聽
AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
if (mediaPlayer == null) {
...
} else if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
// Resume playback
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
am.abandonAudioFocus(afChangeListener);
}
}
};
//在播放的時候為AudioManager添加獲取焦點的監(jiān)聽
int result = mManager.requestAudioFocus(afChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mediaPlayer.start();
}
//在我們不用的時候?qū)⒔裹c釋放掉
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
am.abandonAudioFocus(afChangeListener);
}
AudioManager的常用方法:
adjustStreamVolume(int streamType,int direction, int flags):漸進(jìn)式設(shè)置音量值,調(diào)用一次,提高或降低一單位音量值
參數(shù)一:指定音頻類型,同上
參數(shù)二:
ADJUST_LOWER 降低音量
ADJUST_RAISE 升高音量
ADJUST_SAME 保持不變,這個主要用于向用戶展示當(dāng)前的音量
參數(shù)三:
FLAG_PLAY_SOUND 調(diào)整音量時播放聲音
FLAG_SHOW_UI 調(diào)整時顯示音量條setStreamVolume(int streamType, int index, int flags):直接設(shè)置音量值
參數(shù)一:指定音頻類型,同上
參數(shù)二:音量值
參數(shù)三:同上getMode( ):返回當(dāng)前的音頻模式
setMode( ):設(shè)置音頻模式
MODE_NORMAL(普通),MODE_RINGTONE(鈴聲),
MODE_IN_CALL(打電話),MODE_IN_COMMUNICATION(通話)getRingerMode( ):返回當(dāng)前的鈴聲模式
setRingerMode(int streamType):設(shè)置鈴聲模式
RINGER_MODE_NORMAL(普通)、RINGER_MODE_SILENT(靜音)
RINGER_MODE_VIBRATE(震動)getStreamVolume(int streamType):
獲得手機(jī)的當(dāng)前音量,最大值為7,最小值為0,當(dāng)設(shè)置為0的時候,會自動調(diào)整為震動模式getStreamMaxVolume(int streamType):獲得手機(jī)某個聲音類型的最大音量值
setSpeakerphoneOn(boolean on):設(shè)置是否打開擴(kuò)音器
setMicrophoneMute(boolean on):設(shè)置是否讓麥克風(fēng)靜音
isMicrophoneMute():判斷麥克風(fēng)是否靜音或是否打開
isMusicActive():判斷是否有音樂處于活躍狀態(tài)
isWiredHeadsetOn():判斷是否插入了耳機(jī)
當(dāng)鈴聲模式為震動時需要添加權(quán)限:
<uses-permission android:name=”android.permission.VIBRATE”/>