首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >安卓:戴被报道为连接蓝牙耳机的手表?

安卓:戴被报道为连接蓝牙耳机的手表?
EN

Stack Overflow用户
提问于 2022-06-24 23:25:00
回答 1查看 78关注 0票数 0

我的倒计时应用程序使用文本到语音提供音频倒计时。

当应用程序检测到蓝牙扬声器时,音频会发送给该扬声器。

像三星手表4和TicWatch Pro 3这样的可穿戴设备被报告为耳机!

我最初的onCreate()包括:

代码语言:javascript
复制
// Check if a speaker is connected 
if (bluetoothAdapter.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothHeadset.STATE_CONNECTED) 
    sendSpeechToSpeaker()
else 
    sendSpeechToPhone()

问题1,,对上面的问题是否有一个简单的修正,只会检测连接的耳机?

我的解决办法是单独检查每个连接的蓝牙设备,忽略那些不是耳机的设备。

问题2,,有人能提出比我的解决办法更简单的方法吗?

解决办法

在初始化过程中,每个连接的蓝牙设备都会被检查,如果它们实际上是一个耳机,音频将被重新路由。

检查每个连接设备的btServiceListener

代码语言:javascript
复制
val btServiceListener: ServiceListener = object : ServiceListener {
    // used to scan all CONNECTED Bluetooth devices looking for external speakers ...
    override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
        if (profile == BluetoothProfile.HEADSET) {
            val connectionStates = intArrayOf(BluetoothProfile.STATE_CONNECTED) 
            // get all connected headsets
            val connectedHeadsetList = proxy.getDevicesMatchingConnectionStates(connectionStates)
            for (connectedHeadset in connectedHeadsetList) {
                // check each headset and check if it is ACTUALLY a headset
                val majorMask = BluetoothClass.Device.Major.UNCATEGORIZED // actually want to use BITMASK but some Fwit declared it private !
                val isHeadset = (connectedHeadset.bluetoothClass?.deviceClass?.and(majorMask) == BluetoothClass.Device.Major.AUDIO_VIDEO)
                if (isHeadset) 
                    sendSpeechToSpeaker()
                }
            }
            bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) // here we are finished with the proxy so clear
        }
        override fun onServiceDisconnected(profile: Int) {}
    }

上面的侦听器在onCreate()中被调用

代码语言:javascript
复制
// search the list of connected bluetooth headsets
bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothAdapter = bluetoothManager.adapter
bluetoothAdapter.getProfileProxy(this, btServiceListener, BluetoothProfile.HEADSET);

听者使用大面罩耳机代码是(0x0400)三星Galaxy是可穿戴的(0x0700) TicWatch Pro 3全球定位系统是未分类的(0x1F00)

为了简单起见,我没有显示BTListener中所需的相同代码,以确保如果手表断开连接,它就不会将音频从扬声器发送出去!

EN

回答 1

Stack Overflow用户

发布于 2022-10-25 23:51:02

可以通过直接检查音频属性来避免上述问题,而不是解析每个连接的蓝牙设备。

代码语言:javascript
复制
private fun routeTTSAudioOutput() {
    // on start and when changes are detected ensure audio is being routed correctly
    val bluetoothA2DPConnected = audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP)
    if (bluetoothA2DPConnected) {
        if (!bluetoothSCOTurnedOn) audioManager.startBluetoothSco()
        audioManager.mode = AudioManager.MODE_IN_CALL
    } else {
        if (bluetoothSCOTurnedOn) audioManager.stopBluetoothSco()
        audioManager.mode = AudioManager.MODE_NORMAL
    }
    audioManager.isSpeakerphoneOn = !bluetoothA2DPConnected
    bluetoothSCOTurnedOn = bluetoothA2DPConnected
    bundleTTS = Bundle()
    bundleTTS.putInt(TextToSpeech.Engine.KEY_PARAM_STREAM, audioManager.mode)
    this.runOnUiThread { bluetoothConnectedImageView.visibility = if (bluetoothA2DPConnected) ImageView.VISIBLE else ImageView.INVISIBLE }
}

音频回调使用上述功能将文本路由到语音。

代码语言:javascript
复制
private val audioDeviceCallback : AudioDeviceCallback = object : AudioDeviceCallback() {
    override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>?) {
        super.onAudioDevicesAdded(addedDevices)
        routeTTSAudioOutput()
    }
    override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>?) {
        super.onAudioDevicesRemoved(removedDevices)
        routeTTSAudioOutput()
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72750231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档