android 音頻處理mediaplay介紹
處理音頻焦點(diǎn)
本文引用地址:http://dyxdggzs.com/article/201609/305045.htm盡管某個(gè)時(shí)刻只有一個(gè)activity可以運行,Android卻是一個(gè)多任務(wù)環(huán)境.這對使用音頻的應用帶來(lái)了特殊的挑戰,因為只有一個(gè)音頻輸出而可能多個(gè)媒體都想用它.在A(yíng)ndroid2.2之前,沒(méi)有內建的機制來(lái)處理這個(gè)問(wèn)題,所以可能在某些情況下導致壞的用戶(hù)體驗.例如,當一個(gè)用戶(hù)正在聽(tīng)音樂(lè )而另一個(gè)應用需要通知用戶(hù)一些重要的事情時(shí),用戶(hù)可能由于音樂(lè )聲音大而不能聽(tīng)的通知.從Android2.2開(kāi)始,平臺為應用提供了一個(gè)協(xié)商它們如何使用設備音頻輸出的途徑,這個(gè)機制叫做音頻焦點(diǎn).
當你的應用需要輸出像樂(lè )音和通知之類(lèi)的音頻時(shí),你應該總是請求音頻焦點(diǎn).一旦應用具有了焦點(diǎn),它就可以自由的使用音頻輸出.但它總是應該監聽(tīng)焦點(diǎn)的變化.如果被通知丟失焦點(diǎn),它應該立即殺死聲音或降低到靜音水平(有一個(gè)標志表明應選擇哪一個(gè))并且僅當重新獲得焦點(diǎn)后才恢復大聲播放.
將來(lái)的音頻焦點(diǎn)是合作的.所以,應用被希望(并被強列鼓勵)遵守音頻焦點(diǎn)的方針,但是卻不是被系統強制的.如果一個(gè)應用在丟失音頻焦點(diǎn)后依然想大聲播放音樂(lè ),系統不會(huì )去阻止它.然而用戶(hù)卻體驗很壞并且很想把這鳥(niǎo)應用卸載.
要請求音頻焦點(diǎn),你必須從AudioManager調用requestAudioFocus(),如下所示:
[java]
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// 不能獲得音頻焦點(diǎn)
}
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// 不能獲得音頻焦點(diǎn)
}
requestAudioFocus()的第一個(gè)參數是一個(gè)AudioManager.OnAudioFocusChangeListener,它的onAudioFocusChange()方法在音頻焦點(diǎn)發(fā)改變時(shí)被調用.因此,你也應該在你的service和activity上實(shí)現此接口.例如:
[java]
class MyService extends Service
implements AudioManager.OnAudioFocusChangeListener {
// ....
public void onAudioFocusChange(int focusChange) {
// Do something based on focus change...
}
}
class MyService extends Service
implements AudioManager.OnAudioFocusChangeListener {
// ....
public void onAudioFocusChange(int focusChange) {
// Do something based on focus change...
}
}
參數focusChange告訴你音頻焦點(diǎn)如何發(fā)生了變化,它可以是以上幾種值(它們都是定義在A(yíng)udioManager中的常量):
AUDIOFOCUS_GAIN:你已獲得了音頻焦點(diǎn).
AUDIOFOCUS_LOSS:你已經(jīng)丟失了音頻焦點(diǎn)比較長(cháng)的時(shí)間了.你必須停止所有的音頻播放.因為預料到你可能很長(cháng)時(shí)間也不能再獲音頻焦點(diǎn),所以這里是清理你的資源的好地方.比如,你必須釋放MediaPlayer.
AUDIOFOCUS_LOSS_TRANSIENT:你臨時(shí)性的丟掉了音頻焦點(diǎn),很快就會(huì )重新獲得.你必須停止所有的音頻播放,但是可以保留你的資源,因為你可能很快就能重新獲得焦點(diǎn).
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:你臨時(shí)性的丟掉了音頻焦點(diǎn),但是你被允許繼續以低音量播放,而不是完全停止.
下面是一個(gè)例子:
[java]
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
if (mMediaPlayer == null) initMediaPlayer();
else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
// is likely to resume
if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but it's ok to keep playing
// at an attenuated level
if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
break;
}
}
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
if (mMediaPlayer == null) initMediaPlayer();
else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
評論