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要求使用效果
intAUDIOFOCUS_NONE
用于表示音频焦点增强或音频焦点请求。
API 261.停止其他音频播放
2.本音频播放完毕或者暂停,其他音频也不会恢复播放
intAUDIOFOCUS_GAIN
用于表示持续时间未知的音频焦点增强或音频焦点请求。
1.停止其他音频播放
2.本音频播放完毕或者暂停,其他音频也不会恢复播放
intAUDIOFOCUS_GAIN_TRANSIENT
用于表示暂时的增强或音频聚焦的请求,预期持续很短的时间。临时更改的示例:播放行驶方向或事件通知
1.停止其他音频播放
2.本音频播放完毕或者暂停,其他音频恢复播放
intAUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
用于表示对音频焦点的临时请求,预计会持续很短的时间,在此期间,其他应用程序或系统组件不应播放任何内容。
独占和瞬态音频焦点请求的示例:语音备忘录录制、语音识别.
*在此期间系统不应播放任何通知,媒体播放应暂停。
API 191.停止其他音频播放
2.本音频播放完毕或者暂停,其他音频恢复播放
intAUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
用于表示对音频焦点的临时请求,预期持续很短的时间,并且其他音频应用程序可以在降低输出音量后继续播(也称为“降级”)
其他音频播放音量降低,本音频正常音量播放
intabandonAudioFocus(AudioManager.OnAudioFocusChangeListener l)This method was deprecated in API level 26. use abandonAudioFocusRequest(android.media.AudioFocusRequest)放弃音频焦点。使上一个焦点所有者(如果有)接收焦点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crazy丶code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值