1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Android 【蓝牙4.0 BLE 低功耗可穿戴设备】 开发总结

Android 【蓝牙4.0 BLE 低功耗可穿戴设备】 开发总结

时间:2022-06-10 10:35:55

相关推荐

Android 【蓝牙4.0 BLE 低功耗可穿戴设备】 开发总结

最近在做可穿戴设备APP端的开发,之前没有相关知识的接触(android官方4.3版本才推出),在网上找了许久,资料也特别特别的少,无赖自己参考官方demo和文档。最终还是将设备连接成功,并且可以正常的收发数据命令。(花了我两个礼拜的时间呀!

)以此进行总结,写下这篇博文。源代码就没有上传上来了,因为已经集成到项目APP中了,而这篇博文又是我后来写的。就只能贴上部分代码,希望对BLE刚接触的有少许帮助。

首先你要了解到蓝牙的基本概念及定义术语:

请参考:/zh-weir/archive//04/02/407373.html 【没有接触过BLE的请先看左边的链接】

另外参考了:/forum.php?mod=viewthread&tid=573261&highlight=BLE

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

本文地址:/yybj 转载请注明出处。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

现在开始进入主题:

一、先来介绍几个类 :

BluetoothGatt,BluetoothGattService,BluetoothGattCharacteristic,BluetoothGattCallback

官方介绍网址是:/reference/android/bluetooth/BluetoothGatt.html

①BluetoothGatt

BluetoothGatt 是开发里最重要最常用到的东西了,我把它理解为手机与设备通信的管道。有了这个管道,收发数据就容易了。

BluetoothGatt mBluetoothGatt= bluetoothDevice.connectGatt(this, false, mGattCallback);

这是官方的文档:

————————————————————————————————————————————————————————

publicBluetoothGattconnectGatt(Contextcontext, boolean autoConnect,BluetoothGattCallbackcallback)

Added inAPI level 18

Connect to GATT Server hosted by this device. Caller acts as GATT client. The callback is used to deliver results to Caller, such as connection status as well as any further GATT client operations. The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client operations.

Parameters

autoConnectWhether to directly connect to the remote device (false) or to automatically connect as soon as the remote device becomes available (true).

callbackGATT callback handler that will receive asynchronous callbacks.

Throws

IllegalArgumentExceptionif callback is null

————————————————————————————————————————————————————————

从这个文档我们可以看出autoConnect为false立刻发起一次连接;为true自动连接,只要蓝牙设备变得可用。

实测发现,用false连接比较好,比较快, true会等个十几秒甚至几分钟才会连接上。开发过程中一般都是用false,扫描到bluetoothDevice之后,直接用false连接即可。BluetoothGattCallback 是非常重要的回调函数,手机与蓝牙设备的一切通信结果都在这里体现。待会细讲。

②BluetoothGattService

蓝牙设备所拥有的服务。在这里比喻成【班级】吧。bluetoothDevice就比喻成【学校】吧。 一个学校可以有很多个班级。班级根据UUID来区别。(把这里的UUID当做班级的【班号】)

③BluetoothGattCharacteristic

蓝牙设备所拥有的特征。比喻成【学生】。 一个班级里也可以有很多个学生。学生也是根据UUID 来区别(把这里的UUID当做学生的【学号】)。当你需要用手机来和蓝牙设备通信的时候,就相当于你想和一个学生交流,你得先知道这个学生的学号,所在班级号,就是开发中的所说的CharacUUID, ServiceUUID。

④BluetoothGattCallback

所有操作的回调函数。以下是我重写了它的方法,总共九个。一会慢慢的介绍。

[html]

<prename="code"class="java"><spanstyle="font-size:12px;"></span><prename="code"class="java"><spanstyle="font-size:14px;">/**

*所有操作的回调函数。实现回调方法,监听APP的事件改变。例如,连接和服务发现变化。

*

*<pre>

*1:notification对应onCharacteristicChanged;

*2:readCharacteristic对应onCharacteristicRead;

*3:writeCharacteristic对应onCharacteristicWrite;

*4:连接蓝牙或者断开蓝牙对应onConnectionStateChange;

*5:readDescriptor对应onDescriptorRead;

*6:writeDescriptor对应onDescriptorWrite;

*7:readRemoteRssi对应onReadRemoteRssi;

*8:executeReliableWrite对应onReliableWriteCompleted;

*9:discoverServices对应onServicesDiscovered。

*</pre>

*/

privatefinalBluetoothGattCallbackmGattCallback=newBluetoothGattCallback(){

@Override

publicvoidonConnectionStateChange(BluetoothGattgatt,intstatus,

intnewState){

super.onConnectionStateChange(gatt,status,newState);

}

@Override

publicvoidonServicesDiscovered(BluetoothGattgatt,intstatus){

super.onServicesDiscovered(gatt,status);

}

@Override

publicvoidonCharacteristicRead(BluetoothGattgatt,

BluetoothGattCharacteristiccharacteristic,intstatus){

super.onCharacteristicRead(gatt,characteristic,status);

}

@Override

publicvoidonCharacteristicWrite(BluetoothGattgatt,

BluetoothGattCharacteristiccharacteristic,intstatus){

super.onCharacteristicWrite(gatt,characteristic,status);

}

@Override

publicvoidonCharacteristicChanged(BluetoothGattgatt,

BluetoothGattCharacteristiccharacteristic){

super.onCharacteristicChanged(gatt,characteristic);

}

@Override

publicvoidonDescriptorRead(BluetoothGattgatt,

BluetoothGattDescriptordescriptor,intstatus){

super.onDescriptorRead(gatt,descriptor,status);

}

@Override

publicvoidonDescriptorWrite(BluetoothGattgatt,

BluetoothGattDescriptordescriptor,intstatus){

super.onDescriptorWrite(gatt,descriptor,status);

}

@Override

publicvoidonReliableWriteCompleted(BluetoothGattgatt,intstatus){

super.onReliableWriteCompleted(gatt,status);

}

@Override

publicvoidonReadRemoteRssi(BluetoothGattgatt,intrssi,intstatus){

super.onReadRemoteRssi(gatt,rssi,status);

}

};

</span>

开始来看我们的程序↓↓↓↓

当调用了连接函数mBluetoothGatt =bluetoothDevice.connectGatt(this.context, false, gattCallback);之后,

[java]

/**

*连接断开的状态改变

*/

@Override

publicvoidonConnectionStateChange(BluetoothGattgatt,intstatus,

intnewState){

super.onConnectionStateChange(gatt,status,newState);

//首先判断这个status如果等于BluetoothGatt.GATT_SUCCESS(value=0)代表这个回调是正常的,

//如果不等于0,那边就代表没有成功,也不需要进行其他操作了,

//连接成功和断开连接都会走到这里

if(newState==BluetoothProfile.STATE_CONNECTED){

Log.i("连接与断开","连接GATT服务.");

//连接成功之后,我们应该立刻去寻找服务(上面提到的BluetoothGattService),只有寻找到服务之后,才可以和设备进行通信

mBluetoothGatt.discoverServices();

}elseif(newState==BluetoothProfile.STATE_DISCONNECTED){//断开

Log.i("连接与断开","断开与服务的连接.");

}

}

当判断到连接成功之后,会去寻找服务, 这个过程是异步的,会耗点时间,当寻找到服务之后,会走到回调:

[java]

/**

*服务发现设备

*/

@Override

publicvoidonServicesDiscovered(BluetoothGattgatt,intstatus){

super.onServicesDiscovered(gatt,status);

if(status==BluetoothGatt.GATT_SUCCESS){

//寻找到服务

//寻找服务之后,我们就可以和设备进行通信,比如下发配置值,获取设备电量什么的

readBatrery();//读取电量操作

sendSetting();//下发配置值

}else{

Log.w("服务发现设备","服务发现收到状态:"+status);

}

}

接着看读的方法↓↓↓

[java]

/**

*读操作

*/

privatevoidreadBatrery(){

//如上面所说,想要和一个学生通信,先知道他的班级(ServiceUUID)和学号(CharacUUID)

BluetoothGattServicebatteryService=mBluetoothGatt.getService(UUID

.fromString("0000180f-0000-1000-8000-00805f9b34fb"));//此处的0000180f...是举例,实际开发需要询问硬件那边

if(batteryService!=null){

BluetoothGattCharacteristicbatteryCharacteristic=batteryService

.getCharacteristic(UUID

.fromString("00002a19-0000-1000-8000-00805f9b34fb"));//此处的00002a19...是举例,实际开发需要询问硬件那边

if(batteryCharacteristic!=null){

//读取电量,这是读取batteryCharacteristic值的方法,读取其他的值也是如此,只是它们的ServiceUUID和CharacUUID不一样

mBluetoothGatt.readCharacteristic(batteryCharacteristic);

}

}

}

如果读取电量(或者读取其他值)成功之后 ,会来到回调:

[java]

/**

*设备发来的数据

*/

@Override

publicvoidonCharacteristicRead(BluetoothGattgatt,

BluetoothGattCharacteristiccharacteristic,intstatus){

super.onCharacteristicRead(gatt,characteristic,status);

//读取到值,根据UUID来判断读到的是什么值

if(characteristic.getUuid().toString()

.equals("00002a19-0000-1000-8000-00805f9b34fb")){

//获取到电量

intbattery=characteristic.getValue()[0];

}

}

接下来看写的方法↓ ↓ ↓

[java]

/**

*写操作

*/

privatevoidsendSetting(){

BluetoothGattServicesendService=mBluetoothGatt.getService(UUID

.fromString("00001805-0000-1000-8000-00805f9b34fb"));//此处的00001805...是举例,实际开发需要询问硬件那边

if(sendService!=null){

BluetoothGattCharacteristicsendCharacteristic=sendService

.getCharacteristic(UUID

.fromString("00002a08-0000-1000-8000-00805f9b34fb"));//此处的00002a08...是举例,实际开发需要询问硬件那边

if(sendCharacteristic!=null){

//随便举个数据

sendCharacteristic.setValue(newbyte[]{0x01,0x20,0x03});

//写命令到设备,

mBluetoothGatt.writeCharacteristic(sendCharacteristic);

}

}

}

如果下发命令成功后,会来到回调:

[java]

/**

*write成功(发送值成功)写入Characteristic成功与否的回调可以根据

*characteristic.getValue()来判断是哪个值发送成功了,比如连接上设备之后你有一大串命令需要下发,你调用多次写命令,

*这样你需要判断是不是所有命令都成功了,因为android不太稳定,有必要来check命令是否成功,否则你会发现你明明调用

*写命令,但是设备那边不响应

*/

@Override

publicvoidonCharacteristicWrite(BluetoothGattgatt,

BluetoothGattCharacteristiccharacteristic,intstatus){

switch(status){

//写入成功

caseBluetoothGatt.GATT_SUCCESS:

Log.d("write回调","----写入数据成功!");

byte[]b=characteristic.getValue();

break;

//写入失败

caseBluetoothGatt.GATT_FAILURE:

Log.d("write回调","----写入数据失败!");

break;

//没有写入的权限

caseBluetoothGatt.GATT_WRITE_NOT_PERMITTED:

Log.d("write回调","----没有写入数据的权限!");

break;

}

}

讲解完读写操作,还有一个重要操作就是Notify(通知)。notify 就是让设备 可以发送通知给你,也可以说上报值给你(发送命令给你)。

[java]

<spanstyle="font-size:14px;">/**

*启用或禁用通知给特征。

*

*@paramcharacteristic

*特点采取行动。

*@paramenabled

*如果这为true,启用通知。否则false。

*@return是否成功开启通知

*/

publicbooleanenableNotification(

BluetoothGattCharacteristiccharacteristic,booleanenable){

if(mBluetoothGatt==null||characteristic==null)

returnfalse;

if(!mBluetoothGatt.setCharacteristicNotification(characteristic,

enable))

returnfalse;

BluetoothGattDescriptordescriptor=characteristic.getDescriptor(UUID

.fromString("0000fff7-0000-1000-8000-00805f9b34fb"));

if(descriptor==null)

returnfalse;

if(enable){

descriptor

.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

}else{

descriptor

.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);

}

returnmBluetoothGatt.writeDescriptor(descriptor);

}</span>

一旦设备那边notify 数据给你,你会在回调里收到:

[java]

<spanstyle="font-size:14px;">/**

*收到设备notify值(设备上报值)

*/

@Override

publicvoidonCharacteristicChanged(BluetoothGattgatt,

BluetoothGattCharacteristiccharacteristic){

//收到设备notify值(设备上报值),根据characteristic.getUUID()来判断是谁发送值给你,根据characteristic.getValue()来获取这个值

L.i("收到设备notify值","收到设备notify值");

}</span>

先写到这儿,后续开发在来进行总结。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。