Android蓝牙通信-2016-05-30

近来工作做了很多Android手机对接蓝牙设备的工作,记录一下。

场景

需要对接蓝牙设备,发送或者获取数据,比如蓝牙打印机、蓝牙体脂称、蓝牙电子血压计、蓝牙血糖仪、蓝牙身高尺等等。大致的过程就是手机跟设备互相连接认证,互传数据的过程。当然,对接不同的设备,会有不同的交互流程,同一类设备,针对不同厂商,也需要遵循不同厂商定制的SDK的相关协议。但都离不开蓝牙的核心协议,下面分经典蓝牙2.0以及低功耗蓝牙4.0(BLE)。

经典蓝牙2.0

比较传统的设备只支持蓝牙2.0,SPP协议、HDP协议
过程:扫描,配对,连接,通信

参考:Android 蓝牙开发基本流程

1、通用UUID:
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
2、配对,反射设置密码(如果需要设置的话)
Method removeBondMethod = btClass.getDeclaredMethod("setPin",  new Class[] { byte[].class }); 
return value = (Boolean) removeBondMethod.invoke(bluetoothDevice,  new Object[] { password.getBytes() });
3、配对,反射调用绑定方法
Method createBondMethod = btClass.getMethod("createBond");
Boolean value = (Bovolean) createBondMethod.invoke(btDevice);
4、连接,根据不同SDK方式

问题:getBluetoothService() called with no BluetoothManagerCallback

int sdk = Build.VERSION.SDK_INT;
if (sdk >= 10) {
    socket = mDevice.createInsecureRfcommSocketToServiceRecord(SPP_UUID);
} else {
    socket = mDevice.createRfcommSocketToServiceRecord(SPP_UUID);
}

低功耗蓝牙4.0技术(BLE)

注意:从Android4.3(API-18)开始支持BLE,但只支持作为中心设备模式Central,也就是只支持Android设备主动扫描连接外围设备Peripheral,在Android5.0(API-21)两种模式都支持。蓝牙4.0将三种规格集一体,包括传统蓝牙技术、高速技术和低耗能技术
参考:最全最详细的蓝牙版本介绍包含蓝牙4.0和4.1
过程:扫描,连接,发现服务,通信

1、获取BluetoothAdapter
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
2、判断是否支持蓝牙,并打开蓝牙(利用系统Intent的方式请求打开蓝牙)
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
3、搜索BLE设备
mBluetoothAdapter.startLeScan(mLeScanCallback);
BluetoothAdapter.LeScanCallback // 搜索回调

注意:搜索时,你只能搜索传统蓝牙设备或者BLE设备,两者完全独立,不可同时被搜索。
实际使用:使用经典蓝牙搜索方式startDiscovery()能同时搜索到百捷2.0和百捷4.0的设备

4、连接GATT Server
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
BluetoothGattCallback // 连接回调
5、连接成功。BluetoothGatt常规用到的几个操作示例
connect(); // 连接远程设备。
discoverServices(); // 搜索连接设备所支持的service。
disconnect(); // 断开与远程设备的GATT连接。
close(); // 关闭GATT Client端。
readCharacteristic(characteristic); // 读取指定的characteristic。
setCharacteristicNotification(characteristic, enabled); // 设置当指定characteristic值变化时,发出通知。
getServices(); // 获取远程设备所支持的services。

一些实践心得

关于蓝牙硬件

对接蓝牙设备,一方面由于蓝牙设备的多样性,另一方面Android手机硬件、系统的多样性,会遇到比较多的问题就是蓝牙连接的稳定性问题。关于这个问题也是尝试了很多种方法去避免,分析其中一个原因就是:由代码驱动蓝牙硬件的过程,需要一定的时间,一定的时间等待,会带来极大稳定性的提高。比如启动蓝牙后延迟300ms在执行其他操作。另一个就是可以采用线程轮询判断一个状态是否已经启动,比如循环5次,每隔1秒执行判断操作。

关于优化

必要时,考虑采用服务Service去获取设备的数据,或者设置单例模式。

如有错误,欢迎拍砖!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,476评论 25 708
  • Guide to BluetoothSecurity原文 本出版物可免费从以下网址获得:https://doi.o...
    公子小水阅读 8,322评论 0 6
  • 公司的项目最近需要用到蓝牙开发的相关内容,因此特地查阅了Google官方文档的内容并进行二次整理,希望能对需要学习...
    Chuckiefan阅读 32,577评论 44 123
  • 前言: 本文主要描述Android BLE的一些基础知识及相关操作流程,不牵扯具体的业务实现,其中提供了针对广播包...
    幻影宇寰阅读 5,419评论 6 19
  • 1.时间不受控。 48个人的时间、空间同时对上,可能性为零。即使三分之一的人相聚也变得难上加难。 这是二十年后渐渐...
    高小花0218阅读 268评论 0 0