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 {@Overridepublic void onServiceConnected(int profile, BluetoothProfile proxy) {Log.d(TAG,"Bluetooth service connected profile == "+profile);if (profile == BluetoothProfile.HEADSET_CLIENT) {isHeadSetProfileReady = true;mHeadsetClient = (BluetoothHeadsetClient)proxy;} }@Overridepublic 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);
}

Android 9.0 蓝牙电话BluetoothHeadsetClient相关推荐

  1. mi2 android 5.0 方法,小米2/2S怎么刷Android5.0 小米2/2S刷Android5.0教程【详解】

    在之前,小米MIUI团队就公布了适配小米2的Android5.0运行图片,今天终于放出了适配小米2/2S的Android5.0刷机包,下面就来看看怎么给小米2/2S刷入Android5.0吧. 我们了 ...

  2. 小米2S最新Android版本,小米2/2s如何刷Android 5.0?小米2s升级安卓5.0步骤

    小米2/2s如何刷Android 5.0?如果你不了解小米2s升级安卓5.0步骤的话可以通过下文来了解,小米2s也能够体验最新的安卓系统哦~棒棒糖会给这款手机带来哪些变化呢? 光棍节时候,小米官方开发 ...

  3. android ble 设备扫描程序,Android应用开发Android 7.0 BLE scan 问题:程序无错但扫描不到BLE设备...

    本文将带你了解Android应用开发Android 7.0  BLE scan 问题:程序无错但扫描不到BLE设备,希望本文对大家学Android有所帮助. < 最近在做毕设,需要几周内从头学起 ...

  4. android 5.0 9300,三星Android5.0升级名单曝光 S2止步4.2

    北京时间3月19日消息,据科技网站vr-zone报道,内部消息人士今天曝光了三星Android 5.0系统升级名单,预计三星将为Galaxy S4在内的5款设备提供Android 5.0升级,并有数款 ...

  5. android 8.0可以实现后台包活么,Android 8.0 应用保活实践 · Jaqen Ng

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 虽然我也觉得强行保活应用挺不厚道的,但是没办法,为了完成需求. 一开始尝试的方案是 Android 5.0 后系统提供的 ...

  6. as3 android白屏,Android 8.0中一些坑以及对应的解决方法

    前言 虽然 Android 9.0 都已经面世了,本篇文章写的有点迟了. 但是迟到好过不到,因此基于此这边还是记录一下项目中遇到的 Android 8.0 的坑及对应解决方法. 每次系统升级,虽然系统 ...

  7. visual studio 2017 中默认无法开发 Android 8.0 及以上系统的解决方案

    一般默认比较旧有两个原因,系统版本过旧,Visual Studio 版本过旧. 第一步,将windows 更新到最新版,必须是windows 10 并且更新到最新. 第二步,将visual studi ...

  8. android 动态获取权限有哪些,Android 6.0+ 动态获取权限

    Android 6.0+ 动态获取权限 这里有一个现成的库,可以直接拿来用.方便简单 1.向app下的gradle添加依赖: dependencies{ // android 6.0+ 动态获取权限 ...

  9. android 7.0 短信监控,Android 7.0 监听网络变化的示例代码

    Android7.0前,Android系统前网络切换时,会发广播,业务只要监听广播即可. public class NetChangeReceiver extends BroadcastReceive ...

  10. android下载后的app自动安装,Android 7.0 下载APK后自动安装

    随着Android版本越来越高,Android对隐私的保护力度也越来越大.这些隐私权限的更改在为用户带来更加安全的操作系统的同时也为开发者带来了一些新的任务.如何让你的APP能够适应这些改变而不是崩溃 ...

最新文章

  1. Vmware 安装CentOS7时连不上网问题的解决
  2. Python萌新笔记
  3. Linux/windows com串口 java 接收数据 并解析 web程序
  4. 数值计算原理_JavaScript策略设计时数值计算精度问题解决方案
  5. 百度编辑器复制微信图片无法保存
  6. SCI/SCIE/SSCI/期刊简介及官方查询验证方法
  7. OKR目标管理专题及模板大全
  8. 2021年危险化学品生产单位安全生产管理人员新版试题及危险化学品生产单位安全生产管理人员找解析
  9. java学习笔记20(Lambda表达式、函数式编程、流式计算、练习)
  10. xcpc网络赛个人总结(文笔不好,纯纯记录)
  11. 高分子DBCO-PEG-acid需要存储在-20°C,避光,避湿的环境,DBCO-PEG-COOH,末端羧酸在活化剂(如EDC或HATU)存在下可与伯胺基反应,形成稳定的酰胺键。
  12. POJ1655 树重心模板题
  13. (USB:VCP+HID复合设备与系统配置)
  14. 超越卷积、自注意力:神经网络新算子「内卷(Involution)」
  15. grep -v grep
  16. 1.可编程并行接口实验
  17. Oxford Nanopore MinION Sequencing and Genome Assembly
  18. python获取股票历史数据并保存_Python 股票历史分笔数据读取
  19. nginx启动成功,但是访问不了页面解决办法
  20. 智能视频抠图_‎App Store 上的“智能视频抠图: 一键去背景”

热门文章

  1. 单片机c语言计算器,基于STC89C52单片机的计算器的设计.doc
  2. Html5 打砖块游戏,加入道具和速通模式(含源码)
  3. Javascript ES6集合(SET)类型✪ ω ✪
  4. easyopenjtag使用教程(最新版)
  5. Excel/WPS做数据透视表,即对变量做交叉汇总(列联表)
  6. Wireshark抓包详细分析
  7. ping计算机名获取IP
  8. linux桌面管理器lightdm,linux lightdm gdm gnome kde等的区别于联系(桌面环境 窗口管理器 显示管理器)...
  9. win7系统定时删除数据的批处理命令_win7如何一键清理系统垃圾|win7批处理命令清理垃圾的方法...
  10. 亚信科技收购趋势科技中国