Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting Android Bluetooth Answer/Hangup Button Events

I need to detect when the 'Phone' button is pressed on bluetooth devices, most will have a single button for answer/hangup.

Using audioManager.registerMediaButtonEventReceiver() with the intent filter MEDIA_BUTTON, I am able to detect ALL of the buttons EXCEPT for the phone button (ie: skip next, skip prev, play/pause).

Using the CALL or CALL_BUTTON filters do not work (no event is received).

The default behaviour of the button is to disconnect the audio and switch back to the earpiece. The same behaviour is occurring in the Skype app, however, when making normal GSM calls, the built in phone app handles the button correctly and can ANSWER and HANGUP the call.

I'm trying to find how the Phone app handles this but have not been able to locate the code.

Does anyone know how to correctly detect the Bluetooth Phone button event?

like image 776
behelit Avatar asked Aug 28 '15 03:08

behelit


Video Answer


1 Answers

Had a hard time figuring out how to make this happen and only found a hacky solution for hanging up. I use this code for a SIP calling app. I route the audio of an active conversation to the bluetooth headset setting the audio mode to in communication (audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);). When the hangup button of a bluetooth headset get's pressed during a conversation the intent STATE_AUDIO_DISCONNECTED get's called. I use that intent action to hangup the active call. I use the following call after changing the audio mode (partially used from another source):

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.
                }
            }
        }
    };
}

I hope this helps anyone.

like image 54
jobbert Avatar answered Oct 16 '22 14:10

jobbert