我正在使用VoIP-Android-App。我想在活动中通过已连接的蓝牙耳机接听和拒绝呼叫。
到目前为止我已经尝试过:
- 使用Media Session接收媒体按钮点击。
- 问题:**如果启动BluetoothSCO,则不会收到任何媒体按钮单击。如果不启动BluetoothSCO,则会收到媒体按钮单击,但无法区分长按钮单击和短按钮单击,因为downtime始终为0,键码始终为KEYCODE_MEDIA_PLAY,ACTION_DOWN后紧跟ACTION_UP。只有通过蓝牙连接时才会出现这些问题。如果通过电缆耳机连接,则会收到相应的键码(KEYCODE_HEADSETHOOK),并且downtime不为0。
- 使用BroadcastReceiver侦听蓝牙SCO连接更改。
private val scoReceiver = object : BroadcastReceiver() {
fun onReceive(context: Context, intent: Intent) {
val state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1)
val previousState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, -1)
if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED && previousState == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
Log.e(TAG, "SCO Disconnected")
hangupCall()
}
}
}
protected fun onStart() {
super.onStart()
val intentFilter = IntentFilter()
intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)
registerReceiver(scoReceiver, intentFilter)
}
通过这种方法,我可以检测到用户何时想挂断电话,例如长按蓝牙耳机,因为这会触发SCO断开连接。
- 问题:**无法检测用户是否要接受来电。
- 使用分派键事件、onKeyDown和onKeyUp。
- 问题:**他们根本不会被调用。
有没有人有什么建议或最佳实践如何正确处理蓝牙耳机?任何帮助都非常感谢。提前感谢!
3条答案
按热度按时间h79rfbju1#
在正常和虚拟语音呼叫(包括振铃)期间,蓝牙耳机单元按钮的所有事件都由蓝牙耳机服务内部处理,而不是作为按钮事件广播。蓝牙耳机服务将这些事件重定向到电信框架(应答/挂断呼叫)。
knsnq2tg2#
这些事件在HeadsetStateMachine中进行内部处理(在packages/apps/Bluetooth下)。
这些事件被转发到IBluetoothHeadsetPhone接口。所有事件被转发到的单个应用程序是在运行时通过遵循HeadsetStateMachine.java中的绑定代码来定义的。这是为了允许手机制造商在不使用默认应用程序的情况下将它们转发到自定义手机应用程序而不是默认应用程序。
若要将事件转发到您的应用程序而不是默认电话应用程序,您必须修改aosp代码。您需要在HeadsetStateMachine、BluetoothHeadsetPhone代理或电话应用程序之一拦截事件。
遗憾的是,如果不修改aosp代码,您所寻找的内容目前无法实现。某些耳机(如Plantronics)具有自定义BT事件,这些事件会转发到所有应用程序-某些现有VoIP应用程序支持这些自定义Intent,以支持某些耳机至少应答呼叫。
bxgwgixi3#
您应该使用android电信API并实现
android.telecom.ConnectionService
和android.telecom.Connection
,其中您应该覆盖onAnswer()回调,当您尝试通过蓝牙耳机接听电话时将调用该回调。有关详细信息,请阅读docs -https://developer.android.com/guide/topics/connectivity/telecom/selfManaged