前言
最近比较忙,两三周没有更新简书了,公司正好在做蓝牙BLE的项目,本来觉得挺简单的东西从网上找了个框架,就咔咔地开始搞,搞完以后才发现里面还有不少坑呢,故而写一篇蓝牙BLE入门及爬坑指南,旨在帮助刚入蓝牙BLE的小伙伴们少走弯路。
注:本文所有的具体代码实现都在文章最后的github上
经典蓝牙和蓝牙BLE的区别
说起蓝牙,大家一定听过蓝牙1.0 2.0 3.0 4.0,不过现在已经不再用版本号区分蓝牙了,蓝牙1.0~3.0都是经典蓝牙,在塞班系统就已经开始使用了,确实很经典。有些人一直认为蓝牙4.0就是蓝牙BLE,其实是错误的。因为4.0是双模的,既包括经典蓝牙又包括低能耗蓝牙。经典蓝牙和蓝牙BLE虽然都是蓝牙,但其实还是存在很大区别的。蓝牙BLE相比于经典蓝牙的优点是搜索、连接的速度更快,关键就是BLE(Bluetooth Low Energy)低能耗,缺点呢就是传输的速度慢,传输的数据量也很小,每次只有20个字节。但是蓝牙BLE因为其低能耗的优点,在智能穿戴设备和车载系统上的应用越来越广泛,因此,蓝牙BLE开发已经是我们Android开发不得不去掌握的一门技术了。
蓝牙BLE的简介
蓝牙BLE是在Android4.3系统及以上引入的,但是仅作为中央设备,直到5.0以后才可以既作为中央设备又可以作为周边设备。也就是5.0系统以后,可以手机控制手机了,不过绝大多数的场景手机还是作为中央设备去控制其他的周边设备。Android BLE 使用的蓝牙协议是 GATT 协议。关于这个GATT协议,我就不详细给大家介绍了,放上个链接,感兴趣的可以看一下http://blog.chinaunix.net/uid-21411227-id-5750680.html
Service和Characteristic
Service是服务,Characteristic是特征值。蓝牙里面有多个Service,一个Service里面又包括多个Characteristic,具体的关系可以看图图中画的比较少,实际上一个蓝牙协议里面包含的Service和Characteristic是比较多的 ,这时候你可能会问,这么多的同名属性用什么来区分呢?答案就是UUID,每个Service或者Characteristic都有一个 128 bit 的UUID来标识。Service可以理解为一个功能集合,而Characteristic比较重要,蓝牙设备正是通过Characteristic来进行设备间的交互的(如读、写、订阅等操作)。
小结
经典蓝牙和蓝牙BLE虽然都是蓝牙,但是在连接和数据传递上还是存在很大的区别,而蓝牙BLE依靠着其低能耗的特点,逐渐在智能穿戴设备上占有一席之地。蓝牙BLE基于GATT协议传输数据,提供了Serivice和Characteristic进行设备之间的通讯。以上,就是蓝牙BLE的基本概念,下面开始蓝牙BLE的正式开发!
蓝牙BLE正确开发姿势(本文重点)
第一步:声明蓝牙BLE权限
<!--声明蓝牙权限-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Android6.0系统以上开启蓝牙还需要定位权限,定位权限属于危险权限,需要动态申请,笔者实现的方法是使用了RxPerssion动态库。
/**
* 检查权限
*/
private void checkPermissions() {
RxPermissions rxPermissions = new RxPermissions(MainActivity.this);
rxPermissions.request(android.Manifest.permission.ACCESS_FINE_LOCATION)
.subscribe(new io.reactivex.functions.Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
if (aBoolean) {
// 用户已经同意该权限
scanDevice();
} else {
// 用户拒绝了该权限,并且选中『不再询问』
ToastUtils.showLong("用户开启权限后才能使用");
}
}
});
}
第二步:连接蓝牙前需要初始化的工作
mBluetoothManager= (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter=m