天天看點

Anddroid IM來電鈴聲通過耳機播放

針對問題:使用雲信IM, 帶耳機時,來電鈴聲還是會外放

本文主要内容

1.如何通過耳機播放來電鈴聲

2.如果來電鈴聲播放之前,耳機播放音樂,如何解決鈴聲和音樂同時播放的問題

問題一:

首先雲信IM來電鈴聲是通過AVChatSoundPlayer來播放的,

解決外放問題,需要将

SoundPool

初始化的傳參從

AudioManager.STREAM_RING

改成

AudioManager.STREAM_MUSIC

因為系統鈴聲模式,預設就是外放的

而音樂模式,連接配接了耳機會通過耳機播放鈴聲

代碼

private void initSoundPool() {
        stop();
        if (soundPool == null) {
            soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
            soundPool.setOnLoadCompleteListener(onLoadCompleteListener);

            audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            ringMode = audioManager.getRingerMode();
        }
        registerVolumeReceiver(true);
    }
           

問題二:

如果來電之前,耳機播放音樂,

我們可以通過設定目前

AudioManager

擷取焦點

當鈴聲播放時,我們就能停止音樂,或者音樂作為背景音播放

設定代碼

audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

參數1:

OnAudioFocusChangeListener

我們沒有焦點監聽需求,直接傳null

參數2:

streamType

哪種音頻類型擷取焦點(因為我們

SoundPool

使用了

STREAM_MUSIC

我們這裡也指定

STREAM_MUSIC

類型)

參數3: 擷取焦點的音頻通過哪種方式播放(請參考文末屬性表)

如果通話完成,或者拒絕接聽後,還想繼續自動播放耳機的音樂

可以通過

audioManager.abandonAudioFocus(null);

放棄音頻焦點。使上一個焦點所有者(如果有)接收焦點,這樣音樂就會自動播放了

參數也是

OnAudioFocusChangeListener

我修改的完整代碼

public void stop() {
        LogUtil.d(TAG, "stop");
        if (soundPool != null) {
            if (streamId != 0) {
                soundPool.stop(streamId);
                streamId = 0;
            }
            if (soundId != 0) {
                soundPool.unload(soundId);
                soundId = 0;
            }
        }
        if (isRingModeRegister) {
            registerVolumeReceiver(false);
        }
        if (audioManager != null) {
            audioManager.abandonAudioFocus(null);
        }
    }
    
 private void initSoundPool() {
        stop();
        if (soundPool == null) {
            soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
            soundPool.setOnLoadCompleteListener(onLoadCompleteListener);

            audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            ringMode = audioManager.getRingerMode();
        }
        audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        registerVolumeReceiver(true);
    }
           

代碼中

audioManager != null

判斷,是因為第一次進來audioManager還沒有建立,會報錯。

下表就是對應的幾種類型

類型 方法or屬性 最低API要求 使用效果
int

AUDIOFOCUS_NONE

用于表示音頻焦點增強或音頻焦點請求。

API 26

1.停止其他音頻播放

2.本音頻播放完畢或者暫停,其他音頻也不會恢複播放

int

AUDIOFOCUS_GAIN

用于表示持續時間未知的音頻焦點增強或音頻焦點請求。

1.停止其他音頻播放

2.本音頻播放完畢或者暫停,其他音頻也不會恢複播放

int

AUDIOFOCUS_GAIN_TRANSIENT

用于表示暫時的增強或音頻聚焦的請求,預期持續很短的時間。臨時更改的示例:播放行駛方向或事件通知

1.停止其他音頻播放

2.本音頻播放完畢或者暫停,其他音頻恢複播放

int

AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE

用于表示對音頻焦點的臨時請求,預計會持續很短的時間,在此期間,其他應用程式或系統元件不應播放任何内容。

獨占和瞬态音頻焦點請求的示例:語音備忘錄錄制、語音識别.

*在此期間系統不應播放任何通知,媒體播放應暫停。

API 19

1.停止其他音頻播放

2.本音頻播放完畢或者暫停,其他音頻恢複播放

int

AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK

用于表示對音頻焦點的臨時請求,預期持續很短的時間,并且其他音頻應用程式可以在降低輸出音量後繼續播(也稱為“降級”)

其他音頻播放音量降低,本音頻正常音量播放
int abandonAudioFocus(AudioManager.OnAudioFocusChangeListener l)This method was deprecated in API level 26. use abandonAudioFocusRequest(android.media.AudioFocusRequest) 放棄音頻焦點。使上一個焦點所有者(如果有)接收焦點。