android 蓝牙编程
来源:互联网 发布:淘宝店免费开店要钱吗 编辑:程序博客网 时间:2024/06/18 14:39
前言
最近有一些蓝牙的通信需要做,就研究了一下蓝牙连接相关
- 连接蓝牙电子秤
- 连接pos机打印
其中连接蓝牙电子秤是接收数据
pos机打印是发送数据/接收数据
流程图
流程图画的相当不专业,请自行脑补
核心类
因为这次的电子秤不是4.0的设备,所以没有使用LBE的开发,而是传统的2.0连接方式
BluetoothAdapter
全局变量
protected BluetoothAdapter mAdapter;
获取的方法,在API18下的时候使用的方式和以上的不一样,其实差别不大
if (SDK_INT < 18) { adapter = BluetoothAdapter.getDefaultAdapter();} else { BluetoothManager bm = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); adapter = bm.getAdapter();}
蓝牙使用的是注册广播的方式来获取系统给我们的通知
核心有以下的几种,注册广播的方法自己去搜下吧
BluetoothDevice.ACTION_FOUND//找到设备BluetoothDevice.ACTION_NAME_CHANGED//设备的名字BluetoothAdapter.ACTION_DISCOVERY_FINISHED//扫描结束BluetoothDevice.ACTION_PAIRING_REQUEST//配对请求的放弃BluetoothAdapter.STATE_OFF//蓝牙关闭BluetoothAdapter.STATE_ON//蓝牙开启
连接
一般这种连接应该是全局单例,考虑写在了service中
首先需要扫描所有的蓝牙连接,但是这里有个坑,就是如果你将广播注册在onCreate中和onDestroy,你每次都需要接收系统的广播,如果出现同名或者别的原因,这里就会一直接收广播
所以这里需要动态的将广播注册与反注册
我这里使用的方案请参照流程图
说明
这里是蓝牙2.0的连接代码,LE的连接相关目前还没有做,后续如果有实现的时候也会再写blog
关于UUID
蓝牙连接的UUID是有一套自己的定义规范的,但是目前的厂商不知道为什么大部分习惯都使用同一个UUID,我这里蓝牙称,蓝牙打印机都用的这个
public static final UUID _UUID = java.util.UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
扫描
mAdapter.startDiscovery()
关于找到设备的坑
这里有一些关于设备的坑,有的设备你使用BluetoothDevice.ACTION_FOUND
广播中获取蓝牙设备的名字会发现是空的,这个时候就很尴尬了,使用系统自带的蓝牙扫描也会发现,扫描到的是先MAC地址,然后过几秒更改为名字,这里有另一个广播BluetoothDevice.ACTION_NAME_CHANGED
可以获取到名字
当然蓝牙设备如果自己有登记,最好还是使用mac地址连接匹配最佳,毕竟mac地址轻易不会重复
配对
try { // 连接建立之前的先配对 if (device.getBondState() == BluetoothDevice.BOND_NONE) { Method creMethod = BluetoothDevice.class.getMethod("createBond"); creMethod.invoke(device); } else {//已配对,连接socket connDevice(device); } } catch (Exception e) { // TODO: handle exception //DisplayMessage("无法配对!"); e.printStackTrace(); }
这里如果已经配对,则直接连接,如果没有配对需要先配对,这里只是创建配对请求 ACTION_PAIRING_REQUEST
这个广播用于接收配对请求的发起,然后使用
LogUtils.d(TAG, "manualConn:" + manualConn); if (manualConn) { return; } final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device == null) { return; } LogUtils.d(TAG, device.getName()); if (device.getBondState() != BluetoothDevice.BOND_BONDED) { try { // ClsUtils.setPin(device.getClass(), device, pwd); // 手机和蓝牙采集器配对 LogUtils.d(TAG, "设置pin码" + pwd); ToastUtils.toast(device.getName() + "配对中"); boolean pinResult = device.setPin(pwd.getBytes());// handler.postDelayed(new Runnable() {// @Override// public void run() {// try {// ClsUtils.cancelPairingUserInput(device.getClass(), device);// } catch (Exception e) {// }// }// }, 1000); // 一般调用不成功,前言里面讲解过了 LogUtils.d(TAG, "pinResult:" + pinResult); if (pinResult) { connDevice(device); } else { ToastUtils.toast("pin码不正确,请手动配对电子秤后点击连接"); manualConn = true; } } catch (Exception e) { ToastUtils.toast("请求连接错误..."); } }
这里是直接贴出来了程序中的片段,也会有一些报错,替换为自己的Log/Toast的util就可以了,也可以考虑删除掉,这里注释掉的部分原本是打算关闭配对的连接框的,但是这里有一些其他的问题,不同的rom处理方式不同,有些处理时会将pin码清空导致连接失败,所以这里将这部分代码清空,不关闭了
连接
核心连接代码
socket = device.createInsecureRfcommSocketToServiceRecord(_UUID);socket.connect()
这个要求API>10
题外话我其实现在的minSDK已经是19了,目前google自己都放弃维护低版本了,google chrome都不支持他们了,咱们也没必要继续支持低版本了
连接成功后,可以获取到一个socket连接,可以用这个socket连接获取到相关信息,不管是接收还是发出,通过这个连接就可以具体的获取相关信息
这里只是抛砖引玉
具体的实现后续有时间抽取出来形成一个开源项目再贴吧,项目毕竟是公司的,我这里不方便直接将整个代码贴出来,这个连接的相关代码非常乱
后记
这个蓝牙项目让我感受到了google深深的恶意,整个项目的坑数不胜数,这里先这样吧
- android平台蓝牙编程
- android平台蓝牙编程
- android平台蓝牙编程
- android蓝牙编程
- Android 蓝牙编程基础
- Android 蓝牙编程基础
- android平台蓝牙编程
- android平台蓝牙编程
- android 蓝牙通信编程
- android 蓝牙通信编程
- android平台蓝牙编程
- android平台蓝牙编程
- android 蓝牙通信编程
- android平台蓝牙编程
- Android蓝牙编程入门
- android蓝牙编程问题
- Android蓝牙编程入门
- android平台蓝牙编程
- final关键字
- MySql的安装与卸载
- ecjtu-summer training #3 C 又见GCD HDU 2504
- 专题:后缀数组——维护后缀排名的强大工具
- mysql you have held broken packages.
- android 蓝牙编程
- 垃圾回收机制,如何优化程序
- D
- HDF5 入门
- 终端模拟器Xshell如何编辑和重命名会话
- #HDU4248#A Famous Stone Collector(组合数)
- 【机器人学】机器人开源项目KDL源码学习:(6)笛卡尔空间轨迹规划、圆弧过渡、姿态插值、梯形速度、pathlength
- JavaSE基本语法阶段
- Linux 套接字编程中 bind 错误:bind fail:Address already in use 解决方法