W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
編寫(xiě):kesenhoo - 原文:http://developer.android.com/training/managing-audio/volume-playback.html
良好的用戶體驗(yàn)應(yīng)該是可預(yù)期且可控的。如果我們的應(yīng)用可以播放音頻,那么顯然我們需要做到能夠通過(guò)硬件按鈕,軟件按鈕,藍(lán)牙耳麥等來(lái)控制音量。 同樣地,我們需要能夠?qū)?yīng)用的音頻流進(jìn)行播放(Play),停止(Stop),暫停(Pause),跳過(guò)(Skip),以及回放(Previous)等動(dòng)作,并且并確保其正確性。
為了創(chuàng)建一個(gè)良好的音頻體驗(yàn),我們首先需要知道應(yīng)用會(huì)使用到哪些音頻流。Android為播放音樂(lè),鬧鈴,通知鈴,來(lái)電聲音,系統(tǒng)聲音,打電話聲音與撥號(hào)聲音分別維護(hù)了一個(gè)獨(dú)立的音頻流。這樣做的主要目的是讓用戶能夠單獨(dú)地控制不同的種類(lèi)的音頻。上述音頻種類(lèi)中,大多數(shù)都是被系統(tǒng)限制。例如,除非你的應(yīng)用需要做替換鬧鐘的鈴聲的操作,不然的話你只能通過(guò)STREAM_MUSIC來(lái)播放你的音頻。
默認(rèn)情況下,按下音量控制鍵會(huì)調(diào)節(jié)當(dāng)前被激活的音頻流,如果我們的應(yīng)用當(dāng)前沒(méi)有播放任何聲音,那么按下音量鍵會(huì)調(diào)節(jié)響鈴的音量。對(duì)于游戲或者音樂(lè)播放器而言,即使是在歌曲之間無(wú)聲音的狀態(tài),或是當(dāng)前游戲處于無(wú)聲的狀態(tài),用戶按下音量鍵的操作通常都意味著他們希望調(diào)節(jié)游戲或者音樂(lè)的音量。你可能希望通過(guò)監(jiān)聽(tīng)音量鍵被按下的事件,來(lái)調(diào)節(jié)音頻流的音量。其實(shí)我們不必這樣做。Android提供了setVolumeControlStream()方法來(lái)直接控制指定的音頻流。在鑒別出應(yīng)用會(huì)使用哪個(gè)音頻流之后,我們需要在應(yīng)用生命周期的早期階段調(diào)用該方法,因?yàn)樵摲椒ㄖ恍枰贏ctivity整個(gè)生命周期中調(diào)用一次,通常,我們可以在負(fù)責(zé)控制多媒體的Activity或者Fragment的onCreate()
方法中調(diào)用它。這樣能確保不管應(yīng)用當(dāng)前是否可見(jiàn),音頻控制的功能都能符合用戶的預(yù)期。
setVolumeControlStream(AudioManager.STREAM_MUSIC);
自此之后,不管目標(biāo)Activity或Fragment是否可見(jiàn),按下設(shè)備的音量鍵都能夠影響我們指定的音頻流(在這個(gè)例子中,音頻流是"music")。
許多線控或者無(wú)線耳機(jī)都會(huì)有許多媒體播放控制按鈕,例如:播放,停止,暫停,跳過(guò),以及回放等。無(wú)論用戶按下設(shè)備上任意一個(gè)控制按鈕,系統(tǒng)都會(huì)廣播一個(gè)帶有ACTION_MEDIA_BUTTON的Intent。為了正確地響應(yīng)這些操作,需要在Manifest文件中注冊(cè)一個(gè)針對(duì)于該Action的BroadcastReceiver,如下所示:
<receiver android:name=".RemoteControlReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
在Receiver的實(shí)現(xiàn)中,需要判斷這個(gè)廣播來(lái)自于哪一個(gè)按鈕,Intent通過(guò)EXTRA_KEY_EVENT這一Key包含了該信息,另外,KeyEvent類(lèi)包含了一系列諸如KEYCODE_MEDIA_*
的靜態(tài)變量來(lái)表示不同的媒體按鈕,例如KEYCODE_MEDIA_PLAY_PAUSE 與 KEYCODE_MEDIA_NEXT。
public class RemoteControlReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) {
// Handle key press.
}
}
}
}
因?yàn)榭赡軙?huì)有多個(gè)程序在監(jiān)聽(tīng)與媒體按鈕相關(guān)的事件,所以我們必須在代碼中控制應(yīng)用接收相關(guān)事件的時(shí)機(jī)。下面的例子顯示了如何使用AudioManager來(lái)為我們的應(yīng)用注冊(cè)監(jiān)聽(tīng)與取消監(jiān)聽(tīng)媒體按鈕事件,當(dāng)Receiver被注冊(cè)上時(shí),它將是唯一一個(gè)能夠響應(yīng)媒體按鈕廣播的Receiver。
AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
...
// Start listening for button presses
am.registerMediaButtonEventReceiver(RemoteControlReceiver);
...
// Stop listening for button presses
am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
通常,應(yīng)用需要在他們失去焦點(diǎn)或者不可見(jiàn)的時(shí)候(比如在onStop()方法里面)取消注冊(cè)監(jiān)聽(tīng)。但是對(duì)于媒體播放應(yīng)用來(lái)說(shuō)并沒(méi)有那么簡(jiǎn)單,實(shí)際上,在應(yīng)用不可見(jiàn)(不能通過(guò)可見(jiàn)的UI控件進(jìn)行控制)的時(shí)候,仍然能夠響應(yīng)媒體播放按鈕事件是極其重要的。為了實(shí)現(xiàn)這一點(diǎn),有一個(gè)更好的方法,我們可以在程序獲取與失去音頻焦點(diǎn)的時(shí)候注冊(cè)與取消對(duì)音頻按鈕事件的監(jiān)聽(tīng)。這個(gè)內(nèi)容會(huì)在后面的課程中詳細(xì)講解。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: