BluetoothHeadsetClient
主要实现HFP协议,主要实现拨打、接听、挂断电话(AG侧、HF侧)、切换声道功能。
AG(Audio Gate)音频网关—音频设备输入输出网关 。
HF(Hands Free)免提—该设备作为音频网关的远程音频输入/输出机制,并可提供若干遥控功能。
在车载蓝牙中,手机侧是AG,车载蓝牙侧是HF,在android源代码中,将AG侧称为HFP/AG,将HF侧称为HFPClient/HF。
BluetoothHeadsetClient初始化
/**
* 连接服务
*/
private void getProfileProxy() {
mAdapter.getProfileProxy(mContext, new ProxyServiceListener(), BluetoothProfile.HEADSET_CLIENT);
}
private final class ProxyServiceListener implements BluetoothProfile.ServiceListener {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
Log.d(TAG,"Bluetooth service connected profile == "+profile);
if (profile == BluetoothProfile.HEADSET_CLIENT) {
isHeadSetProfileReady = true;
mHeadsetClient = (BluetoothHeadsetClient)proxy;
}
}
@Override
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET_CLIENT) {
isHeadSetProfileReady = false;
mHeadsetClient = null;
}
}
}
BluetoothHeadsetClient连接设备
//获取连接状态
public int getConnectionState() {
if (mHeadsetClient != null) {
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
return BluetoothProfile.STATE_DISCONNECTED;
} else {
return mHeadsetClient.getConnectionState(deviceList.remove(0));
}
}
return BluetoothProfile.STATE_DISCONNECTED;
}
//连接远程设备
public boolean connect(BluetoothDevice device) {
if (null != mHeadsetClient) {
return mHeadsetClient.connect(device);
}
Log.i(TAG,"connect mHeadsetClient == "+mHeadsetClient);
return false;
}
//断开连接
public boolean disconnect(BluetoothDevice device) {
if (null != mHeadsetClient) {
return mHeadsetClient.disconnect(device);
}
Log.i(TAG, "disconnect mHeadsetClient == "+mHeadsetClient);
return false;
}
BluetoothHeadsetClient控制声音通道
// Initiates a connection of audio channel.
public boolean connectAudio() {
Log.d(TAG, "hangup clicked isHeadsetReady:" + isHeadSetProfileReady + ", mHeadset:" + mHeadsetClient);
if (isHeadSetProfileReady && mHeadsetClient != null) {
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
return false;
} else {
setSpeakerPhoneOn(true);
BluetoothDevice mDevice = deviceList.remove(0);
return mHeadsetClient.connectAudio(mDevice);
}
}
return false;
}
// Disconnects audio channel.
public boolean disconnectAudio() {
Log.d(TAG, "hangup clicked isHeadsetReady:" + isHeadSetProfileReady + ", mHeadset:" + mHeadsetClient);
if (isHeadSetProfileReady && mHeadsetClient != null) {
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
return false;
} else {
setSpeakerPhoneOn(false);
BluetoothDevice mDevice = deviceList.remove(0);
return mHeadsetClient.disconnectAudio(mDevice);
}
}
return false;
}
BluetoothHeadsetClient电话
// 拨号
public void dial(String number) {
Log.d(TAG, "dial clicked mIsProfileReady:" + isHeadSetProfileReady + ", mHeadsetClient:" + mHeadsetClient);
if (!mAdapter.isEnabled() || mHeadsetClient == null) {
ToastUtil.showToast(mContext, mContext.getResources().getString(R.string.bt_disable));
return;
}
if (isHeadSetProfileReady && mHeadsetClient != null) {
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
ToastUtil.showToast(mContext, mContext.getResources().getString(R.string.text_tips_disconnected));
}else {
BluetoothDevice mDevice = deviceList.remove(0);
setSpeakerPhoneOn(true);
mHeadsetClient.dial(mDevice, number);
}
}
}
// 挂断所有电话
public void terminateCall(int callNumber) {
Log.d(TAG, "terminate clicked isHeadsetReady:" + isHeadSetProfileReady + ", mHeadset:" + mHeadsetClient);
if (isHeadSetProfileReady && mHeadsetClient != null) {
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
ToastUtil.showToast(mContext, mContext.getResources().getString(R.string.text_tips_disconnected));
} else {
setSpeakerPhoneOn(false);
BluetoothDevice mDevice = deviceList.remove(0);
List<BluetoothHeadsetClientCall> calls = mHeadsetClient.getCurrentCalls(mDevice);
if (!calls.isEmpty()) {
BluetoothHeadsetClientCall call = calls.remove(callNumber);
mHeadsetClient.terminateCall(mDevice,call);
}
}
}
}
//接听来电
public void acceptCall(int flag) {
Log.d(TAG, "hangup clicked isHeadsetReady:" + isHeadSetProfileReady + ", mHeadset:" + mHeadsetClient);
if (isHeadSetProfileReady && mHeadsetClient != null) {
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
ToastUtil.showToast(mContext, mContext.getResources().getString(R.string.text_tips_disconnected));
} else {
setSpeakerPhoneOn(true);
BluetoothDevice mDevice = deviceList.remove(0);
mHeadsetClient.acceptCall(mDevice,flag);
}
}
}
//挂断来电
public void hangup() {
Log.d(TAG, "hangup clicked isHeadsetReady:" + isHeadSetProfileReady + ", mHeadset:" + mHeadsetClient);
if (isHeadSetProfileReady && mHeadsetClient != null) {
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
ToastUtil.showToast(mContext, mContext.getResources().getString(R.string.text_tips_disconnected));
} else {
setSpeakerPhoneOn(false);
BluetoothDevice mDevice = deviceList.remove(0);
mHeadsetClient.rejectCall(mDevice);
}
}
}
//发送DTMF
public void sendDTMF(byte code) {
if (!mAdapter.isEnabled() || mHeadsetClient == null) {
ToastUtil.showToast(mContext, mContext.getResources().getString(R.string.bt_disable));
return;
}
Log.d(TAG, "sendDTMF() Enter. with" + code);
List<BluetoothDevice> deviceList = mHeadsetClient.getConnectedDevices();
if (deviceList.isEmpty()) {
ToastUtil.showToast(mContext, mContext.getResources().getString(R.string.text_tips_disconnected));
} else {
BluetoothDevice mDevice = deviceList.remove(0);
Log.d(TAG, "mConnStat is " + mConnStat);
if (mConnStat == BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) {
mHeadsetClient.sendDTMF(mDevice, code);
} else {
Log.d(TAG, "mConnStat is not CALL_STATE_ACTIVE");
}
}
}
//三方ANSWER_AND_HOLD
bluetoothHeadsetClient.acceptCall(BluetoothDevice,BluetoothHeadsetClient.CALL_ACCEPT_HOLD);
//三方ANSWER_AND_TERMINATE
bluetoothHeadsetClient.acceptCall(BluetoothDevice,BluetoothHeadsetClient.CALL_ACCEPT_TERMINATE);
//获取信号强度
Bundle bundle = bluetoothHeadsetClient.getCurrentAgEvents(BluetoothDevice);
if (bundle != null && bundle.containsKey(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH))
{
return bundle.getInt(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH);
}