AudioFocus的申請與釋放

  • 場景:當(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”/>


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 教程一:視頻截圖(Tutorial 01: Making Screencaps) 首先我們需要了解視頻文件的一些基...
    90后的思維閱讀 4,988評論 0 3
  • Media Playback Android多媒體框架包涵了對播放多種通用媒體的類型的支持,所以你可以很容易的集成...
    VegetableAD閱讀 980評論 0 0
  • Linear PCM 在介紹Core Audio之前,先介紹一下最常用的非壓縮數(shù)字音頻格式Linear PCM(線...
    huangjun0閱讀 5,000評論 0 2
  • 安卓平臺和聲音錄制與播放相關(guān)的主要是4個類:MediaRecorder,MediaPlayer,SoundPool...
    閑庭閱讀 10,886評論 1 47
  • Android音頻收集和播放(一) 一、文章說明 這是自己第一次通過寫文章的方式來記錄在開發(fā)中的一些心得,在這里也...
    熊熊熊孩子閱讀 12,726評論 13 49

友情鏈接更多精彩內(nèi)容