仿微信实现听筒和扬声器切换功能(Android)

3,909 阅读1分钟
object PlayerModeManager {
    enum class PlayMode {
        Speaker,//外放
        Headset,//耳机
        Receiver//听筒
    }
    
    private lateinit var audioManager: AudioManager
    private const val AUDIO_PLAY_IS_SPEAKER_ON = "audio_play_is_speaker_on"
    private const val defaultIsOpenSpeaker = false//默认听筒模式
    private var playMode = PlayMode.Speaker
    fun init(application: Application) {
        audioManager = application.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        setSpeakerOn(defaultIsOpenSpeaker)//设置默认是听筒模式
        
        val intentFilter = IntentFilter()
        intentFilter.addAction(Intent.ACTION_HEADSET_PLUG)
        //监听耳机的插拔
        application.registerReceiver(object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                if (intent?.action == Intent.ACTION_HEADSET_PLUG) {
                    val state = intent.getIntExtra("state", 0)
                    if (state == 1) {
                        playMode = PlayMode.Headset
                        changeMode()
                    } else if (state == 0) {
                        playMode = if (isSpeakerOn()) PlayMode.Speaker else PlayMode.Receiver
                        changeMode()
                    }
                    
                }
            }
        }, intentFilter)
    }
    
    
    /**
     *  判断 当前是否是扬声器模式
     *  (注:当前只是记录值 可能也是耳机模式 耳机模式下允许切换模式 但是只有拔下耳机时才生效)
     */
    fun isSpeakerOn(): Boolean {
        return PreferenceManager.getDefaultSharedPreferences(UIUtils.getContext())
            .getBoolean(AUDIO_PLAY_IS_SPEAKER_ON, defaultIsOpenSpeaker)
    }
    
    
    /**
     *   设置播放模式
     */
    fun setSpeakerOn(isSpeaker: Boolean) {
        PreferenceManager.getDefaultSharedPreferences(UIUtils.getContext()).edit()
            .putBoolean(AUDIO_PLAY_IS_SPEAKER_ON, isSpeaker).apply()
        if (playMode != PlayMode.Headset) {
            playMode = if (isSpeaker) PlayMode.Speaker else PlayMode.Receiver
            changeMode()
        }
    }
    
    /**
     * 切换到外放
     */
    private fun changeToSpeaker() {
        val audioManager =
            UIUtils.getContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager
        audioManager.mode = AudioManager.MODE_NORMAL
        audioManager.isSpeakerphoneOn = true
    }
    
    /**
     * 切换到耳机模式
     */
    private fun changeToHeadset() {
        audioManager.isSpeakerphoneOn = false
    }
    
    /**`
     * 切换到听筒
     */
    private fun changeToReceiver() {
        audioManager.isSpeakerphoneOn = false
        audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
        
    }
    
    /**
     * 更换模式
     */
    private fun changeMode() {
        if (!isPlaying) return
        when (playMode) {
            PlayMode.Receiver -> changeToReceiver()
            PlayMode.Speaker  -> changeToSpeaker()
            PlayMode.Headset  -> changeToHeadset()
        }
    }
    
    /**
     * 判断当前是否是听筒模式
     * (注:播放时切换到听筒模式 前1-2s 可能无声音 建议 在听筒模式下延迟1-2s播放)
     */
    fun isReceiver(): Boolean {
        return playMode == PlayMode.Receiver
    }
    
    private var isPlaying = false
    /**
     * 播放时语音时 调用该方法 屏蔽第三方音乐 同时使当前播放模式生效
     */
    fun onPlay() {
        isPlaying = true
        audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
            AudioManager.AUDIOFOCUS_GAIN)
        changeMode()
    }
    
    /**
     * 语音停止播放时 调用该方法 恢复第三方音乐播放  恢复播放模式
     */
    fun onStop() {
        isPlaying = false
        audioManager.abandonAudioFocus(null)
        audioManager.mode = AudioManager.MODE_NORMAL
    }
    
    
}