检测Android蓝牙应答/挂机按钮事件



我需要检测当蓝牙设备上按下'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.
                }
            }
        }
    };
}

最新更新