Android?音頻焦點(diǎn)(Audio?Focus)

Android 音頻焦點(diǎn)(Audio Focus)


引子

說(shuō) Audio Focus 前先說(shuō)個(gè)很簡(jiǎn)單需求:來(lái)電時(shí)暫停正在播放的音樂(lè)双泪,電話結(jié)束時(shí)恢復(fù)播放争便。


音頻焦點(diǎn)

問(wèn)題的解決方法就是:請(qǐng)求系統(tǒng)的音頻焦點(diǎn)(Request the Audio Focus)。


官方文檔指出Android 在處理音頻播放是分了多個(gè)“音頻流”的稽犁,如音樂(lè)流、音效流、電話聲音流等蛙酪,使控制音量時(shí)可以互不干涉。多數(shù)情況下我們播放音樂(lè)都是使用 STREAM_MUSIC 音頻流翘盖。

另外桂塞,系統(tǒng)中可能會(huì)有多個(gè)應(yīng)用程序會(huì)播放音頻,所以需要考慮他們之間該如何協(xié)調(diào)馍驯,為了避免同時(shí)播放音樂(lè)阁危,Android 系統(tǒng)使用音頻焦點(diǎn)來(lái)進(jìn)行統(tǒng)一管理,即只有獲得了音頻焦點(diǎn)的應(yīng)用程序才可以播放音樂(lè)汰瘫。


那么狂打,播放音頻應(yīng)該這樣來(lái)做:


獲取音頻焦點(diǎn) requestAudioFocus

獲取成功后,開(kāi)始播放音頻

處理音頻焦點(diǎn)的丟失和“DUCK”

播放完畢后取消焦點(diǎn)

如此便可以完美的解決引子里的需求混弥。


一個(gè)簡(jiǎn)單的示例

MusicService.java

public class MusicService extends Service {

? ? private AudioManager mAm;

? ? private boolean isPlaymusic;

? ? private String url;

? ? private MediaPlayer mediaPlayer;

? ? @Override

? ? public void onCreate() {

? ? ? ? super.onCreate();

? ? ? ? mAm = (AudioManager) getSystemService(AUDIO_SERVICE);

? ? }

? ? @Override

? ? public void onStart(Intent intent, int startId) {

? ? ? ? if (intent != null) {

? ? ? ? ? ? Bundle bundle = intent.getExtras();

? ? ? ? ? ? if (bundle != null) {

? ? ? ? ? ? ? ? isPlaymusic = bundle.getBoolean("isPlay", true);

? ? ? ? ? ? ? ? url = bundle.getString("url");

? ? ? ? ? ? ? ? if (isPlaymusic)

? ? ? ? ? ? ? ? ? ? play();

? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? ? ? stop();

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {

? ? public void onAudioFocusChange(int focusChange) {

? ? if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {

? ? // Pause playback

? ? pause();

} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {

// Resume playback

resume();

} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {

// mAm.unregisterMediaButtonEventReceiver(RemoteControlReceiver);

mAm.abandonAudioFocus(afChangeListener);

// Stop playback

stop();

}

}

};

private boolean requestFocus() {

// Request audio focus for playback

int result = mAm.requestAudioFocus(afChangeListener,

// Use the music stream.

AudioManager.STREAM_MUSIC,

// Request permanent focus.

AudioManager.AUDIOFOCUS_GAIN);

return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;

}

private void resume() {

if (mediaPlayer != null) {

mediaPlayer.start();

}

}

private void pause() {

if (mediaPlayer != null && mediaPlayer.isPlaying()) {

mediaPlayer.pause();

}

}

OnCompletionListener completionListener = new OnCompletionListener() {

@Override

public void onCompletion(MediaPlayer player) {

if(!player.isLooping()){

mAm.abandonAudioFocus(afChangeListener);

}

}

};

private void play() {

if (requestFocus()) {

if (mediaPlayer == null) {

try {

mediaPlayer = new MediaPlayer();

mediaPlayer.setDataSource(url);

mediaPlayer.prepare();

mediaPlayer.setOnCompletionListener(completionListener);

} catch (IOException e) {

e.printStackTrace();

}

}

if (!mediaPlayer.isPlaying()) {

mediaPlayer.start();

}

}

}

@Override

public void onDestroy() {

super.onDestroy();

if (mediaPlayer != null)

mediaPlayer.release();

}

private void stop() {

if (mediaPlayer != null) {

mediaPlayer.stop();

}

}

@Override

public IBinder onBind(Intent arg0) {

// TODO Auto-generated method stub

return null;

}

}

經(jīng)模擬器測(cè)試趴乡,當(dāng)來(lái)電時(shí)音頻焦點(diǎn)會(huì)給到鈴聲流,并打出日志:


I/AudioService(1235):? AudioFocus? requestAudioFocus() from AudioFocus_For_Phone_Ring_And_Calls

此時(shí)MusicService中的afChangeListener會(huì)得到AUDIOFOCUS_LOSS_TRANSIENT,于是會(huì)暫停播放音頻晾捏。

當(dāng)通話結(jié)束或者掛掉電話官辽,afChangeListener會(huì)得到AUDIOFOCUS_GAIN,于是恢復(fù)播放音頻粟瞬。


注意:

播放完畢一定要禁止掉請(qǐng)求的音頻焦點(diǎn)abandonAudioFocus(afChangeListener)同仆,否則,如果播放完畢后的某個(gè)時(shí)段剛好有個(gè)通話結(jié)束裙品,并且此時(shí)沒(méi)有其他的應(yīng)用占用了焦點(diǎn)俗批,系統(tǒng)會(huì)重新通知服務(wù)里的afChangeListener,導(dǎo)致音頻再次的播放市怎。

如果丟失的短暫音頻焦點(diǎn)允許DUCK狀態(tài)AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK岁忘,在這種情況下,應(yīng)用程序降低音量繼續(xù)播放区匠,不需要暫停干像。再次獲取后,恢復(fù)原來(lái)的音量驰弄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末麻汰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子戚篙,更是在濱河造成了極大的恐慌五鲫,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岔擂,死亡現(xiàn)場(chǎng)離奇詭異位喂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)乱灵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門塑崖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人痛倚,你說(shuō)我怎么就攤上這事规婆。” “怎么了状原?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵聋呢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我颠区,道長(zhǎng)削锰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任毕莱,我火速辦了婚禮器贩,結(jié)果婚禮上颅夺,老公的妹妹穿的比我還像新娘。我一直安慰自己蛹稍,他們只是感情好吧黄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著唆姐,像睡著了一般拗慨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奉芦,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天赵抢,我揣著相機(jī)與錄音,去河邊找鬼声功。 笑死烦却,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的先巴。 我是一名探鬼主播其爵,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伸蚯!你這毒婦竟也來(lái)了摩渺?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤朝卒,失蹤者是張志新(化名)和其女友劉穎证逻,沒(méi)想到半個(gè)月后乐埠,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體抗斤,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年丈咐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瑞眼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棵逊,死狀恐怖伤疙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辆影,我是刑警寧澤徒像,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站蛙讥,受9級(jí)特大地震影響锯蛀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜次慢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一旁涤、第九天 我趴在偏房一處隱蔽的房頂上張望翔曲。 院中可真熱鬧,春花似錦劈愚、人聲如沸瞳遍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掠械。三九已至,卻和暖如春注祖,著一層夾襖步出監(jiān)牢的瞬間份蝴,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工氓轰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婚夫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓署鸡,卻偏偏與公主長(zhǎng)得像案糙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子靴庆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容