Android中如何实现蓝牙的配对与连接
Android中如何实现蓝牙的配对与连接
这段时间在项目中负责做蓝牙的设置模块,蓝牙这部分不算简单,自己先是花了一些时间看系统的蓝牙设置代码,感觉有点熟了才开动的,但期间还是踩了不少坑,有些问题网上也搜不到,现在做完了,有一些心得,记录下来。
1. AndroidManifest中添加蓝牙管理权限
<uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
2. 打开蓝牙
打开蓝牙有两种方式,发送蓝牙开启请求或代码后台自动打开蓝牙。
2.1 发送蓝牙开启请求
先判断BluetoothAdapter是不是为空,为空有可能是系统没有蓝牙模块,再判断蓝牙的状态是不是开启的,不是开启的就发送请求。
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();if (btAdapter != null && !btAdapter.isEnabled()) { Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivity(intent)}
2.2 后台自动打开蓝牙
if (btAdapter != null && !btAdapter.isEnabled()) { btAdapter.enable();}
3. 获取已经绑定(配对)的设备
Set<BluetoothDevice> bondedDevices = btAdapter.getBondedDevices(); //返回已绑定的蓝牙设备集
BluetoothDevice有如下方法: getBondState() //获取设备绑定状态,BOND_NONE(未绑定), BOND_BONDING(正在绑定), BOND_BONDED(已绑定) getType() //获取蓝牙类型,DEVICE_TYPE_CLASSIC(普通类型BR/EDR), DEVICE_TYPE_LE(低功耗类型), DEVICE_TYPE_DUAL(双类型BR/EDR/LE), DEVICE_TYPE_UNKNOWN(未知) getAddress() //蓝牙地址 getBluetoothClass() //获取蓝牙类别(BluetoothClass),如手机、电脑、耳机,注意与蓝牙类型的区别 getName() //蓝牙设备名字
BluetoothClass蓝牙类别说明: 目前有12个大类,定义在BluetoothClass.Device.Major下BITMASK、MISC、COMPUTER、PHONE、NETWORKING、AUDIO_VIDEO、PERIPHERAL、IMAGING、WEARABLE、TOY、HEALTH、UNCATEGORIZED
每个大类有若干个小类别,定义在BluetoothClass.Device下 如: AUDIO_VIDEO_WEARABLE_HEADSET、AUDIO_VIDEO_HANDSFREE、AUDIO_VIDEO_RESERVED、AUDIO_VIDEO_MICROPHONE、AUDIO_VIDEO_LOUDSPEAKE
4. 监听蓝牙设备的变化
// 监听蓝牙设备的变化IntentFilter filter = new IntentFilter();filter.addAction(BluetoothDevice.ACTION_FOUND); //发现新设备filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); //绑定状态改变filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); //开始扫描filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); //结束扫描filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); //连接状态改变filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); //蓝牙开关状态改变BluetoothReceiver receiver = new BluetoothReceiver();mActivity.registerReceiver(receiver, filter);
...
private class BluetoothReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { switch(intent.getAction()) { case BluetoothAdapter.ACTION_FOUND: //获取扫描到的设备 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //判断扫描到的设备是不是在已绑定设备列表中,在就跳过 for (BluetoothDevice d: bondedDevices) { if (d.getAddress().equals(device.getAddress())) { return; } } mScannedDevices.add(device); break;
case BluetoothAdapter.ACTION_DISCOVERY_STARTED: //开始扫描 break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED: //结束扫描 break;
case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED: //绑定状态改变 break;
case BluetoothAdapter.ACTION_STATE_CHANGED: //蓝牙开关状态改变 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: break; case BluetoothAdapter.STATE_ON: break; } break; } }}
5. 绑定蓝牙设备
绑定比较简单,调用 BluetoothDevice的createBond就一句代码,调用后就开始尝试绑定。
private boolean createBond(BluetoothDevice device) { return device.createBond();}
绑定成功后会触发刚注册的蓝牙监听器,action为 ACTION_BOND_STATE_CHANGED
6. 取消绑定
BluetoothDevice绑定的方法是开放的,取消绑定的方法却是隐藏的,只对系统app开放,坑爹,只能用反射来解决了。
private boolean removeBond(BluetoothDevice device) { Class btDeviceCls = BluetoothDevice.class; Method removeBond = btDeviceCls.getMethod("removeBond"); removeBond.setAccessible(true); return (boolean) removeBond.invoke(device);}
7. 连接
绑定(配对)和连接是两个不同的过程,绑定是指两个设备发现了对方的存在,可以获取到对方的名称、地址等信息,有能力建立起连接;连接是指两个设备共享了一个RFCOMM通道,有能力进行数据互传。确认绑定上了之后,才能开始连接。可以试试蓝牙音箱的连接过程,就是先点击一次,开始配对,配对成功后出现在已绑定的列表中,再点击一次,就开始连接,连接成功后蓝牙音箱就有声音了。
这一步我吃了不少亏,网上搜到的都是下面的这种连接方式
UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");private void connect(BluetoothDevice device) { BluetoothSocket socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID); socket.connect(); ...
socket.close();}
这种连接是用蓝牙来进行Socket通信的,而我要做的是如何把手机上连上蓝牙耳机或蓝牙音箱,这种方式是不行的。
折腾了好久,最后找到了下面的连接方法,专门针对AUDIO、VIDEO类型的蓝牙设备的连接。
if (device.getBluetoothClass().getMajorDeviceClass() != BluetoothClass.Device.Major.AUDIO_VIDEO) { return; } btdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { BluetoothHeadset bluetoothHeadset = (BluetoothHeadset) proxy; Class btHeadsetCls = BluetoothHeadset.class; try { Method connect = btHeadsetCls.getMethod("connect", BluetoothDevice.class); connect.setAccessible(true); connect.invoke(bluetoothHeadset, device); } catch (Exception e) { Log.e(TAG, e + ""); } }
@Override public void onServiceDisconnected(int profile) {
} }, BluetoothProfile.HEADSET);
Android中如何实现蓝牙的配对与连接相关推荐
- android中的无线通信蓝牙
一.蓝牙基础知识 蓝牙(Bluetooth)是一种短距离的无线通信技术标准.这个名子来源于10世纪丹麦国王Harald Blatand,英文名子是Harold Bluetooth. (一)蓝牙的四层协 ...
- android中如何实现蓝牙后台运行,Android实现的简单蓝牙程序示例
本文实例讲述了Android实现的简单蓝牙程序.分享给大家供大家参考,具体如下: 我将在这篇文章中介绍了的Android蓝牙程序.这个程序就是将实现把手机变做电脑PPT播放的遥控器:用音量加和音量减键 ...
- 蓝牙的配对和连接的建立过程
蓝牙的建立过程是一个复杂的过程,即使有过相当一段工作和使用经验的人,如果不仔细去了解还是理解不全. 平时我们用蓝牙耳机听音乐,和不同的设备共享文件,打电话等,都有一个配对--连接--传输数据的过程. ...
- win10蓝牙已配对连接不上_Win10系统显示蓝牙已配对但未连接咋办?
电脑的蓝牙设备是我们在Win10系统中电脑传输,接收文件有的小伙伴在使用的方式,安全快捷,今天看到有小伙伴在使用蓝牙的时候初选了问题,系统显示蓝牙已配对了的,但是一直不能成功连接的情况,遇到这个问题我 ...
- Android中Audio框架
原址 原文链接 Android中的音频硬件抽象层(HAL)连接android.media中高层的,特定音频框架API到底层的音频驱动和硬件 下列图表描述了音频功能是如何实现的,以及相关实现的相关源代码 ...
- android ping网络连接服务器失败,Android 中网络连接检测和使用ping检测网络是否可访问...
Android开发中网络相关的检测包括网络是否正常连接和网络已连接但是否可以正常访问两类. (1)其中最常用的就是网络连接是否正常的检测,具体的代码如下:ConnectivityManager con ...
- Android 中网络连接检测和使用ping检测网络是否可访问
Android开发中网络相关的检测包括网络是否正常连接和网络已连接但是否可以正常访问两类. (1)其中最常用的就是网络连接是否正常的检测,具体的代码如下: ConnectivityManager co ...
- win10蓝牙已配对连接不上_Win10系统蓝牙配对手机连接不成功的解决方法
Win10系统蓝牙配对手机连接不成功的解决方法.很多的Win10用户都在使用蓝牙连接手机,一些网友在连接时出现win10系统蓝牙已配对但连接不成功,出现在这样的问题怎么解决呢?下面我们来看看Win10 ...
- Android中ping检测的使用
Ping是Windows.Unix和Linux系统下的一个命令.ping也属于一个通信协议,是TCP/IP协议的一部分.利用"ping"命令可以检查网络是否连通,可以很好地帮助我们 ...
最新文章
- 多版本python共存,安装三方库到指定python版本 多Python版本和虚拟环境
- oracle错误15260,【案例】Oracle报错ORA-00600 2663 产生的原因和解决办法
- java 搜索业务怎么写_Java项目实战第11天:搜索功能的实现
- Windows下Git的安装和基本使用、搭建Git服务器
- MVC数据的注册及验证简单总结
- javaweb学习总结(九):通过Servlet生成验证码图片
- iBATIS.NET 学习笔记(八)
- 单招计算机专业考多少分可以录取,单招考多少分能过?单招分数线
- 通过路由远程计算机重启,华为无线路由器三种常用重启的方法
- 第48次《中国互联网络发展状况统计报告》
- 排序 给excel_excel排序技巧:这些不同方式的排序方法你都会了么
- EXPRESS项目PM2启动NODE_ENV传参数不生效问题解决方法
- 《嵌入式系统开发之道——菜鸟成长日志与项目经理的私房菜》——01-05 基本职能:老鸟也曾是菜鸟...
- 2018年度中国LC3盛大召开!
- 使用C语言--判断素数的两种方法
- linux罗马数字1到10怎么打,罗马数字怎么打
- MK808 vs Raspberry Pi
- shader篇-渲染纹理
- 数组公式和普通公式,差别在于思维方式的不同! 要用看数组的方式看待数据
- 关于结构体,枚举,联合的一些知识
热门文章
- 玩游戏键盘一按就打开计算机,win10电脑玩游戏时按键盘会自动弹字
- 《Java150道面试题全集》
- Python实践 - 网络爬虫笔记 - 1、对 URL 的 get 请求
- [Elasticsearch] 邻近匹配 (三) - 性能,关联单词查询以及Shingles
- 上市公司内审工作内容有哪些
- 1970 matla 时间_教你用MATLAB做季节性调整
- pygame绘制简单游戏——壁球(图像型,节奏型)
- 为什么互联网企业 争做路由器?
- python第一个发行版本由c语言实现_1 晓白的python逆袭之旅基础篇---第一章
- kubekey部署k8s集群