我需要检测当蓝牙设备上按下'Phone'按钮时,大多数将有一个接听/挂断按钮。
使用audioManager.registerMediaButtonEventReceiver()
与意图过滤器MEDIA_BUTTON,我能够检测除了电话按钮的所有按钮(即:跳过下一步,跳过前奏,播放/暂停)。
使用CALL或CALL_BUTTON过滤器不起作用(没有接收到事件)。
该按钮的默认行为是断开音频并切换回耳机。同样的行为也发生在Skype应用程序中,然而,当进行正常的GSM呼叫时,内置的电话应用程序正确地处理按钮,可以接听和挂断呼叫。
我正试图找到手机应用程序如何处理此问题,但未能找到代码。
有人知道如何正确检测蓝牙手机按钮事件吗?
很难想出如何做到这一点,只找到了一个挂电话的hack解决方案。我将此代码用于SIP呼叫应用程序。我将正在进行的会话的音频路由到蓝牙耳机,将音频模式设置为通信(audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);)
。当蓝牙耳机的挂机按钮在对话中被按下时,意图STATE_AUDIO_DISCONNECTED被调用。我使用那个intent动作挂起活动调用。在改变音频模式后,我使用以下调用(部分从另一个来源使用):
public class BluetoothIntentListener {
private static final String TAG = "BluetoothIntent";
private static BluetoothIntentListener bluetoothIntentListener;
protected BluetoothAdapter mBluetoothAdapter;
protected BluetoothHeadset mBluetoothHeadset;
protected AudioManager mAudioManager;
private Context context;
private BluetoothIntentListener(Context context) {
this.context = context;
}
public static BluetoothIntentListener getInstance(Context context) {
if (bluetoothIntentListener == null) {
bluetoothIntentListener = new BluetoothIntentListener(context);
}
return bluetoothIntentListener;
}
public void init() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (mAudioManager.isBluetoothScoAvailableOffCall()) {
mBluetoothAdapter.getProfileProxy(context, mHeadsetProfileListener, BluetoothProfile.HEADSET);
}
}
}
public void destroy() {
mHeadsetProfileListener.onServiceDisconnected(BluetoothProfile.HEADSET);
}
protected BluetoothProfile.ServiceListener mHeadsetProfileListener = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceDisconnected(int profile) {
try {
context.unregisterReceiver(mHeadsetBroadcastReceiver);
mBluetoothHeadset = null;
} catch (IllegalArgumentException il) {
Log.i(TAG, "Headset broadcast receiver wasn't registered yet.");
}
}
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
context.registerReceiver(mHeadsetBroadcastReceiver,
new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED));
IntentFilter f = new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
f.setPriority(Integer.MAX_VALUE);
context.registerReceiver(mHeadsetBroadcastReceiver, f);
}
};
protected BroadcastReceiver mHeadsetBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
int state;
if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED);
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
Log.d(TAG, "Connected");
} else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
// Hangup of bluetooth headset pressed.
}
}
}
};
}