Android BLE的总结

其实BLE是个通用的技术术语,与平台无关的,即ios和Android以及一些嵌入式系统或单片机都可以有BLE模块。在进行Android BLE相关的应用开发前,我们有必要去了解蓝牙协议的一些知识。

蓝牙协议

蓝牙协议基础概念

蓝牙协议包括两种技术:Basic Rate(简称BR)和Low Energy(简称LE)。这两种技术,都包括搜索管理,连接管理等机制,但它们是不能互通的。

Basic Rate是正宗的蓝牙技术,可以包括可选的EDR(Enhanced Data Rate)技术,以及交替使用的MAC(Media Access Control)层和PHY层扩展(简称AMP)。也就是说,BR和EDR是可以同时存在的,但BR/EDR和AMP只能二选一。其中在传输速率上:BR < EDR < AMP。因为AMP借用了WIFI的MAC和物理层。

BR的发展路线是传输越快越好,但是功耗比较严重,而在某些场景下,是比较关注设备的功耗的,于是BLE就产生了,也即Bluetooth LE。

蓝牙系统的组成涉及Bluetooth Application,Bluetooth Core,Bluetooth Host,Bluetooth Controller等。

蓝牙协议规定了两个层次的协议,分别为蓝牙核心协议(Bluetooth Core)和蓝牙应用层协议(Bluetooth Application)。蓝牙核心协议关注对蓝牙核心技术的描述和规范,它只提供基础的机制,并不关心如何使用这些机制。蓝牙应用层协议,是在蓝牙核心协议的基础上,根据具体的应用需求定义出各种各样的策略。

Bluetooth Core由两部分组成,Host和Controller。这两部分在不同的蓝牙技术中(BR/EDR,AMP,LE),承担角色略有不同,但大致的功能是相同的。Controller负责定义RF,Baseband等偏硬件的规范,并在这之上抽象出用于通信的逻辑链路(Logical Link);Host复杂在逻辑链路的基础上,进行更为友好的封装,这样就可以屏蔽掉蓝牙技术的细节,让Bluetooth Application 更为方便的使用。

在一个蓝牙系统中,Host只有一个,但Controller可以一个,也可以有多个。

协议架构

蓝牙协议是通信协议的一种,为了把复杂问题简单化,任何通信协议都具有层次性,特点如下:

(1)从下到上分层,通过层层封装,每一层只需要关心特定,独立的功能,易于实现和维护。

(2)在通信实体内部,下层向上层提供服务,上层是下层的用户

(3)在通信实体之间,协议仅针对每一层,实体之间的通信,就像每一层之间的通信一样,这样有利于交流,理解,标准化。

蓝牙协议分为四个层次:

(1)物理层(Physical Layer):负责提供数据传输的物理通道(通常称为信道)。通常情况下,一个通信系统中存在几种不同类型的信道

(2)逻辑层(Logical Layer):在物理层的基础上,提供两个或多个设备之间,和物理无关的逻辑传输通道

(3)L2CAP Layer:L2CAP是逻辑链路控制和适配协议的缩写,负责管理逻辑层提供的逻辑链路。基于该协议,不同Application可共享同一个逻辑链路

(4)应用层(APP Layer):基于L2CAP提供的channel,实现各种各样的应用功能。Profile是蓝牙协议的特有概念,为了实现不同平台下的不同设备的互联互通,蓝牙协议不止规定了核心规范,也为各种不同的应用场景,定义了各种Application规范,这些应用层规范称作蓝牙profile.

物理层又分为物理信道(Physical Channel)与物理链路(Physical Link)。蓝牙协议为BR/EDR,LE和AMP三种技术定义了8种类型的物理信道:

1.AMP physical channel:主要用于已连接设备之间的数据通信。

2.BR/EDR Basic Piconet Physical Channel:主要用在处于连接状态的蓝牙设备之间的通信,使用全部79个跳频点。

3.BR/EDR Adapted Piconet Physical Channel:也是主要用在处于连接状态的蓝牙设备之间的通信,但是使用较少的RF跳频点,但跳频数目不能少于20个

4.BR/EDR Page Scan Physical Channel:用于蓝牙设备的发现操作,即我们常用的搜索其它蓝牙设备(discover)以及被其它蓝牙设备搜索(discoverable)

5.BR/EDR Inquiry Scan Physical Channel:用于蓝牙设备的连接操作,即我们常用的连接其它蓝牙设备(connect)以及被其它蓝牙设备连接(connectable)。

6.BR/EDR Synchronization Scan Channel:可用于无连接的广播通信。

7.LE Piconet Channel:采用跳频技术用在处于连接状态的蓝牙设备之间的通信

8.LE Advertisement Broadcast Channel用于在设备间进行无连接的广播通信,这些广播通信可用于蓝牙的设备的发现,连接操作,也可用于无连接的数据传输。而物理链路则是对这些物理信道的进一步封装。物理链路只是一个虚拟概念,不对应协议中任何的实体,数据包封包/解包的过程中不被体现。大家只需要知道物理链路是对于物理信道的抽象封装,以便上层使用。

逻辑层也可以分为两部分,分别为Logic Links 和Logic Transports。逻辑层的主要功能,是在已连接的蓝牙设备之间,基于物理链路,建立逻辑信道。蓝牙逻辑信道的划分依据是传输类型,主要包括下面3类:

1.用于管理底层物理链路的控制类传输,包括AMP-C,ACL-C,PSB-C,LE-C,ADVB-C

2.传输用户数据的用户类传输,包括AMP-U,ACL-U,PSB-U,LE-U,ADVB-U.

3.其它比较特殊的传输类型,包括流式传输(stream),PBD(Profile Broadcast Data)
以上每种Logic Link都会在下层对应一个Logic Transport,这些Logical Transport具有一些属性值,如流控,应答/重传机制等。

L2CAP是Logical Link Control and Adaptation Protocol(逻辑链路控制和适配协议)的缩写。对下,它在用户类XXX-U Logical Link的基础上,抽象出和具体技术无关的数据传输通道(包括单播和广播两类),至此用户就不再需要关心繁杂的蓝牙技术细节。对上,它以L2CAP channel endpoints的概念,为具体的应用程序(profile)提供独立的数据传输通道.

profile是蓝牙Application的代指,也可以翻译为服务,为了实现不同平台下的不同设备的互联互通,蓝牙协议为各种可能的,有通用意义的应用场景,都制定了规范。

蓝牙规范有两类:一类是蓝牙核心规范,由Bluetooth Core Specification定义,囊括到L2CAP层,以及相关的核心profile;另一类是蓝牙Application规范,包含了各种各样的profile规范。

至此为止,关于协议的东西就不在这里阐述了,因为东西比较多,而且不是很好理解,这个东西我们只需要简单的了解一下有个印象,当工作环境中遇到蓝牙协议相关的任务或者问题时,再深入研究是比较合理的做法。

下面简要概述两点:1.BLE广播包的格式2.BLE的地址

(1)BLE广播包格式:

1.BLE中有两种角色Central和Peripheral,也就是中心设备和外围设备。中心设备可以主动连接外围设备,外围设备发送广播或者被中心设备连接。外围通过广播被中心设备发现,广播中带有外围设备自身的相关信息。广播包有两种:广播包(Advertising Data)和响应包(Scan Response),其中广播包是每个设备必须广播的,而响应包是可选的。每个包都是31字节,数据包中分为有效数据(significant)和无效数据(non-significant)两部分。

有效数据部分:包含若干个广播数据单元,称为AD Structure。AD Structure的组成是:第一个字节是长度值Len,表示接下来的Len个字节是数据部分。数据部分的第一个字节表示数据的类型AD Type,剩下的Len-1个字节是真正的数据AD data。其中AD type非常关键,决定了AD Data的数据代表的是什么和怎么解析。

无效数据部分:因为广播包的长度必须是31个byte,如果有效数据部分不到31字节,剩下的就用0补全。这部分的数据是无效的,解释的时候,可以忽略。

下面简单看一下主要的几个AD Type的类型:

1.Flags:type=0x01.这个数据用来标识设备LE物理连接的功能。DATA是0到多个字节的Flag值,每个bit上用0或者1来表示是否为True.如果有任何一个bit不为0,并且广播包是可连接的,就必须包含此数据。各bit的定义如下:
bit 0: LE有限发现模式
bit 1: LE普通发现模式
bit 2: 不支持BR/EDR
bit 3: 对Same Device Capable(Controller)同时支持BLE和BR/EDR
bit 4: 对Same Device Capable(Host)同时支持BLE和BR/EDR
bit 5~7: 预留。

2.Service UUID:广播数据中一般都会把设备支持的GATT Service广播出来,用来告诉外面本设备所支持的Service。有三种类型的UUID:16bit,32bit,128bit。广播中,
每种类型有两个类别:完整和非完整的。这样就共有6种AD Type。
非完整的16 bit UUID列表:TYPE=0x02;
完整的16 bit UUID列表: TYPE=0x03;
非完整的32 bit UUID列表:TYPE=0x04;
完整的32 bit UUID列表:TYPE=0x05;
非完整的128 bit UUID列表:TYPE=0x06;
完整的128 bit UUID列表:TYPE=0x07;

3.Local Name:设备名字,DATA是名字的字符串。Local Name可以是设备的全名, 也可以是设备名字的缩写,其中缩写必须是全名的前面的若干字符。
 设备全名:TYPE=0x08;
 设备简称:TYPE=0x09;
 

5.厂商自定义数据:TYPE=0xFF,厂商自定义的数据中,前两个字节表示厂商ID,剩下的是厂商自己按照需求添加,里面的数据内容自己定义。

(2)BLE的地址:

BLE设备有多种类型的设备地址,如Public Device Address,Random Device Address,Static Device Address,Private Device Address等等。有一点需要大家知道的是一个BLE设备可以使用两种类型的地址(一个BLE设备可同时具备两种地址):Public Device Address和Random Device Address。而Random Device Address又分为static Device Address和Private Device Address两类。其中Private Device Address 又可以分为Non-resolvable Private Address和Resolvable Private Address。

1.Public Device Address:该地址可以理解为TCP/IP网络中的MAC地址,是设备的唯一标识地址, 该地址是需要花钱买的,由IEEE保证地址的唯一性。

2.Random Device Address:BLE协议新增的一种地址,该地址不是固定分配的,而是在设备启动后随机生成的。该类型地址可以分为Static Device Address 和Private Device Address两类。该类地址的产生原因主要是Public Device Address需要购买,管理也比较麻烦。

3.Static Device Address:设备在上电时随机生成的地址,在一个上电周期内保持不变,下一次上电的时候可以改变。但不是强制的,因此也可以保持不变。如果改变,上次保存的连接等信息,将不再有效。

4.Private Device Address:Static Device Address通过地址随机生成的方式,解决了部分问题,Private Device Address则更进一步,通过定时更新和地址加密两种方法,提高蓝牙地址的可靠性和安全性。根据地址是否加密,Private Device Address又分为两类,Non-resolvable private address和Resolvable private address。

5.Non-resolvable private address:Non-resolvable private address 和Static Device Address类似,不同之处在于,Non-resolvable private address会定时更新。更新的周期是由GAP规定的,称作T_GAP(private_addr_int),建议值是15分钟。

6.Resolvable private address:Resolvable private address比较有用,它通过一个随机数和一个称作identity resolving key(IPK)的密码生成,因此只能被拥有相同IPK的设备扫描到,可以防止被未知设备扫描和追踪。注意:Resolvable private address不能单独使用,因此需要使用该类型的地址的话,设备要同时具备Public Device Address或者Static Device Address中的一种.

Android 蓝牙简介

Android提供默认的蓝牙协议栈是BlueDroid,分为两层:蓝牙嵌入式系统(BTE)和蓝牙应用层(BTA),BTE层主要实现蓝牙的核心功能,BTA层则主要负责和Android框架通信.
我们在官网上可以看到下面两幅图:

Android 7.x and earlier architecture

蓝牙系统服务通过JNI来与蓝牙协议栈交互,通过Binder IPC来与应用层交互。系统服务给开发者提供各种蓝牙Profile的访问.Android中的蓝牙总体架构主要分为如下几个部分:

1.应用框架层 Application framework在应用框架层是具体的蓝牙相关应用的代码,这里使用android.bluetooth相关的API来和蓝牙硬件交互。其内部实现是通过Binder IPC机制来调用Bluetooth进程的。

2.蓝牙系统服务 Bluetooth system service蓝牙系统服务位于packages/apps/Bluetooth,被作为一个Android的系统App.它在Android框架层实现了蓝牙的Service和Profile,并通过JNI调用到HAL层。编译到系统中就是/system/app/Bluetooth.apk;

3.JNI与android.bluetooth对应的JNI代码位于packages/apps/Bluetooth/jni,JNI层代码调用到HAL层,并当发生某些蓝牙动作的时候,接受来自HAL层的回调.

4.硬件抽象层HAL定义了android.bluetooth API和蓝牙进程需要用到的标准接口,你必须实现这些接口来确保你的蓝牙硬件正常工作。蓝牙HAL相关的头文件位于
hardware/libhardware/include/hardware/bluetooth.h
hardware/libhardware/include/hardware/bt_*.h;

5.蓝牙协议栈:Android提供的默认蓝牙协议栈位于external/bluetooth/bluedroid。这个协议栈实现了通用的蓝牙HAL接口,并且可以通过扩展(Extentions)和配置(Configuration)来自定义。编译到系统中就是/system/lib/hw/bluetooth.default.so;

6.供应商(Vendor extentions):供应商也可以通过创建libbt-vendor并指定这些模块,来添加自定义扩展和HCI层跟踪。

蓝牙的HAL相关文件在hardware/libhardware/include/hardware/,包括但不局限于以下的文件:
bluetooth.h:这里包含蓝牙硬件的接口定义;
bt_gatt.h,bt_gatt_client.h,和bt_gatt_server.h:这里包含GATT profile相关的接口定义;
bt_hf.h:HEP profile相关接口的定义;
bt_hh.h:HID host profile相关接口的定义;
bt_hl.h:HDP profile 相关接口的定义;
bt_mce.h:MAP profile 相关接口的定义;
bt_pan.h:PAN profile 相关接口的定义;
bt_rc.h:AVRCP profile 相关接口的定义;
bt_sock.h:RFCOMM profile 相关接口的定义;

值得注意的是,Android中蓝牙并不局限于HAL中暴露的这些特性和Profile。BlueDroid是蓝牙协议栈的默认是实现,它实现了默认的HAL以及额外的自定义特性。BlueDroid的代码在external/bluetooth/bluedroid目录.

Android 8.0 architecture

通过这两幅图我们可以看到,Android 8.0的蓝牙架构和Android7.x以及之前版本还是有差别的。主要差别在供应商的扩展方式上,Android 8.0和以前版本之间的本地蓝牙堆栈的最大变化是使用高音。Android 8.0中的供应商实现必须使用HIDL而不是libbt-vendor。

另外Android 8.0 通过增加以下功能,增强了平台对蓝牙的支持:
支持 AVRCP 1.4 标准,该标准支持音乐库浏览。
支持蓝牙低功耗 (BLE) 5.0 标准。
将 Sony LDAC 编解码器集成到蓝牙堆叠中。

AirSync协议

AirSync是微信硬件平台提供的一种微信客户端与蓝牙设备间通讯的技术协议,它允许蓝牙设备与微信客户端之间收发数据,并支持通过微信客户端透传到远程服务器。该技术在支持微信互联的蓝牙手环、血压计、智能秤、血糖仪等设备上有比较多的应用.AirSync支持经典蓝牙和BLE低功耗蓝牙.同时AirSync协议又称为微信蓝牙外设协议,具体的协议文档在http://iot.weixin.qq.com/wiki/new/index.html?page=6-1 处下载。

下面我给出实现AirSync协议的测试工具的日志,供相关开发人员进行参考调试:

*****************BLEXXXXX*********************** onTestBroadcastRecord *****result = true, Has 0xfee7 or standard service in broadcast record广播包:02 01 18 0B 09 41 61 5A 45 4E 2D 33 43 44 35 09 FF 01 01 64 1B 13 45 97 93 03 03 E7 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00***** onTestManufatureData *****resut= true, 广播包中 manufacture specific data 字段中MAC地址校验成功.***** onDiscoverService *****result = true, DiscoverService successDiscovered ServicesServiceUUID: 00001801-0000-1000-8000-00805f9b34fbServiceUUID: 00001800-0000-1000-8000-00805f9b34fbServiceUUID: 0000fee7-0000-1000-8000-00805f9b34fb***** onTestHasWeChatService *****result = true, has WeChatService or standard service***** onTestHasIndicateCharacteristic *****result = true, has WeChat Indicate Characteristic***** onTestHasWriteCharacteristic *****result = true, has Wechat Write Characteristic***** onTestHasReadCharacteristic *****result = true, Has WeChat read characteristic***** onTestWriteCharacteristicPermisson *****result = true, has Write permission***** onTestIndicateCharacteristicPermisson *****result = true, has Indication permission***** onTestReadCharacteristicPermisson *****result = true, Read Characteristic is read able***** onTestStartIndicating *****result = true, can Start Indicate***** onConnected *****result = true, connected------onDataReceived------data length = 8data dump = FE 01 00 1A 27 11 00 01data receive seq = 1------onDataReceived------data length = 18data dump = 0A 00 18 81 8C 08 20 01 28 02 3A 06 64 1B 13 45 97 93data receive seq = 2***** onTestRecvAuthReqtWhenStartedIndicating *****result = true, received auth request pack***** onTestIsValidAuthReqPack *****result = true, is a valid auth request packAuthRequestPack: FE 01 00 1A 27 11 00 01 0A 00 18 81 8C 08 20 01 28 02 3A 06 64 1B 13 45 97 93has BaseRequestno Md5DeviceTypeAndDeviceId field!has MacAddress field, Mac Address = 64 1B 13 45 97 93MacAddress BitLength = 48bitMac Address from broadcast record = 64:1B:13:45:97:93Mac address checkout successhas ProtoVersion field, ProtoVersion = 132609has AuthProto field, AuthProto = 1has AuthMethod field, AuthMethod = EAM_macNoEncryptno AesSign field!**** send auth response ****data len = 14data dump = FE 01 00 0E 4E 21 00 01 0A 02 08 00 12 00------onDataReceived------data length = 8data dump = FE 01 00 13 27 13 00 01data receive seq = 3------onDataReceived------data length = 11data dump = 0A 00 12 01 01 1A 04 00 01 02 03data receive seq = 4***** onTestRecvInitReqPack *****result = true, received init request pack***** onTestIsValidInitReqPack *****result = true, valid init request pack: has BaseRequesthas RespFieldFilter field, RespFieldFilter = 01has Challenge field, Challenge = 00 01 02 03**** send init request response ****data len = 47data dump = FE 01 00 2F 4E 23 00 01 0A 02 08 00 10 B4 24 18 F8 AC 01 20 93 8C E6 DD 08 5A 14 57 65 43 68 61 74 20 54 65 73 74 20 62 79 20 6D 61 74 74 21------onDataReceived------data length = 19data dump = FE 01 00 13 27 12 00 01 0A 00 12 05 0A 03 08 C8 01 18 01data receive seq = 5***** onTestIsValidWristbandRequest *****result = true, is a valid WristbandRequest pack.has 1 StepDataItems***********StepDataItemIndex: 0 ************has field uint32 Step, Step = 200*** receive SendDataRequest ****date type = wxWristBand datadata len = 11data dump = 0A 00 12 05 0A 03 08 C8 01 18 01**** send SendData Response(echo request) ****data len = 25data dump = FE 01 00 19 4E 22 00 01 0A 02 08 00 12 0B 0A 00 12 05 0A 03 08 C8 01 18 01***** onTestIsValidSendDataRequest *****result = true, is a valid SendDataRequest pack: has BaseRequest fieldhas Data field, data = 0A 03 08 C8 01has Type field, type = 1, wxWristBand data**** send ManufactureSvr Push ****data len = 22data dump = FE 01 00 16 75 31 00 00 0A 00 12 08 31 32 33 34 35 36 37 38 18 00**** send Html Push ****data len = 23data dump = FE 01 00 17 75 31 00 00 0A 00 12 08 31 32 33 34 35 36 37 38 18 91 4E**** send wxWristBand Push ****data len = 14data dump = FE 01 00 0E 75 31 00 00 0A 00 12 00 18 01**** send EnterDeviceChatView Push ****data len = 14data dump = FE 01 00 0E 75 32 00 00 0A 00 10 01 18 01**** send Exit ChatView Push ****data len = 14data dump = FE 01 00 0E 75 32 00 00 0A 00 10 02 18 01**** send Enter HtmlChatView Push ****data len = 14data dump = FE 01 00 0E 75 32 00 00 0A 00 10 01 18 02**** send Exit HtmlChatView Push ****data len = 14data dump = FE 01 00 0E 75 32 00 00 0A 00 10 02 18 02**** send enterBackground Push ****data len = 12data dump = FE 01 00 0C 75 33 00 00 0A 00 10 01**** send enterForground Push ****data len = 12data dump = FE 01 00 0C 75 33 00 00 0A 00 10 02**** send enterSleep Push ****data len = 12data dump = FE 01 00 0C 75 33 00 00 0A 00 10 03*****Disconnected Device*****

PS:如果你正在Android系统上集成AirSync协议,看完了蓝牙外设协议,内心有一万头神兽的话,这里给你几点建议:

1.把文档多阅读几遍,最起码得有3遍吧,什么看了5遍还是无从下手,连个Demo都没有,只有一些开发板的Demo,看不懂c,网上没有相关有用的资料,于是一万头变两万头。

2.无从下手怎么办,咦,官方给了一个测试工具apk,这个是Java实现的,就是它,反编译它,扒光它,于是思路就有了,直接把里面的部分代码提炼出一部分,连数据包处理的代码都有了。

3.”00002902-0000-1000-8000-00805f9b34fb”这个UUID文档中是没有,但是在开发中,这个又是必须的,这个UUID还是反编译测试工具找到的,这个算是一个深坑,坑了我一整天。

具体的就不说太多了,BLE在Android开发中本来就很小众,这个AirSync协议就小小众,在开发过程中可以参考上面的测试完成的Log,有问题的可以留言,我会尽量回答。

蓝牙精简协议

微信蓝牙精简协议支持智能手环等计步类设备接入微信运动。微信蓝牙计步器Profile协议是基于GATT的协议,该协议对设备的硬件能力要求较低,并且厂商不需要有和微信对接的后台服务器(即只需要开发设备).该profile可以让计步器和微信连接,并传输步数,公里数,卡路里,运动目标等.

这个协议相比于AirSync协议在开发上就简单许多,如果AirSync协议都实现了的话,这个一天就搞定了。

关于AirSync协议与蓝牙精简协议这里说的比较简单,但在开发过程中会遇到各种问题,比如,Android 没有获取广播信道地址的API,Android BLE的广播信道地址是随机的等问题,这个就需要大家看源码和自己在framework层增加相应的API了。

最后同样的给出一份Log:

*****************BLE: XXXXX*********************** onTestBroadcastRecord *****result = true, Has 0xfee7 in broadcast record广播包:02 01 18 0B 09 41 61 5A 45 4E 2D 33 43 30 31 09 FF 01 01 64 1B 13 6A 0D 52 03 03 E7 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00***** onTestManufatureData *****resut= true, 广播包中 manufacture specific data 字段中MAC地址校验成功.***** onDiscoverService *****result = true, DiscoverService successDiscovered ServicesServiceUUID: 00001801-0000-1000-8000-00805f9b34fbServiceUUID: 00001800-0000-1000-8000-00805f9b34fbServiceUUID: 0000fee7-0000-1000-8000-00805f9b34fb***** onTestHasWeChatService *****result = 0has WeChatService and has profile***** onTestHasReadCharacteristic *****result = true, has read characteristic***** onTestPedometerMeasureCharacteristic *****result = true, has WeChat PedometerMeasurement Characteristic***** onTestPedometerTargetCharacteristic *****result = true, Has Wechat PedometerTarget Characteristic***** onTestReadCharacteristicPermisson *****result = true, ReadCharacteristic can read**** onTestMeasurementCharacteristicProperties ****result = true, PedometerMeasureCharacteristic can indicate/notify and read !****onTestTargetCharacteristicProperties****result = true, PedometerTargetCharacteristic can write read and indcate!------onDataReceived------data length = 4data dump = 00 00 04 7Ddata receive seq = 1*****onPedometerMeasurementIndicate*****result = false,Received Data error:数据格式不正确!------onDataReceived------data length = 4data dump = 01 7D 04 00data receive seq = 1*****onPedometerMeasurementIndicate*****result = true,Received Data:步数:1149------onDataReceived------data length = 6data dump = 64 1B 13 6A 0D 52data receive seq = 1*****onRecieveExtraData*****result = false,Received Data error:数据格式不正确!***** onTestStartIndicating *****result = true, can Start Indicate***** onConnected *****result = true, connected------onDataReceived------data length = 4data dump = 01 7D 04 00data receive seq = 1*****onPedometerMeasurementIndicate*****result = true,Received Data:步数:1149//保证这个正确就可以,就可以在微信运动中看到自己的步数了------onDataRead------data length = 4data dump = 01 7D 04 00*****onPedometerMeasurementRead*****result = true,Received Data:步数:1149------onDataReceived------data length = 4data dump = 01 10 27 00data receive seq = 3*****onPedometerTargetIndicate*****result = true,Received Data:步数:10000------onDataRead------data length = 4data dump = 01 10 27 00*****onPedometerTargetRead*****result = true,Received Data:步数:10000*****onPedometerTargetWrite*****result = true,Write Data:数据包一共[4]字节 一共分成[1]数据包 每个数据大小为[20]字节 全部数据包发送成功

以上内容如有任何不对的烦请指出。
转载请注明出处:http://blog.csdn.net/android_jiangjun/article/details/77113883

参考资料:
http://www.wowotech.net/sort/bluetooth
https://race604.com/android-bluetooth-intro/
https://race604.com/ble-advertising/
http://iot.weixin.qq.com/wiki/new/index.html
https://source.android.com/devices/bluetooth/#architecture-android-80

更多相关文章

  1. Android(安卓)Kiosk 模式
  2. Android触摸屏坐标转换
  3. ANDROID Porting系列八、Keymaps and Keyboard Input
  4. [Google Android] GCM: Getting Started
  5. android开发中adb的用法
  6. 最佳的免费移动设备的原型模板文件下载
  7. 【Android】 Android-wifi 直连 wifi direct wifi p2p
  8. A​n​d​r​o​i​d​ ​B​l​u​e​t​o​o​t​h​详​解(And
  9. Android关于arm64-v8a、armeabi-v7a、armeabi、X86的so文件兼容

随机推荐

  1. Android(安卓)SystemUI中HOME key的处理
  2. 初识Android(安卓)Adapter
  3. Android(安卓)29 创建文件夹失败
  4. Android8.1 Launcher3 去掉抽屉(一)
  5. android jni 学习笔记2
  6. Mac上配置gradle遇到的问题
  7. 关于自定义控件和属性时TypedArray.getDi
  8. spring cloud+spring boot+redis社交电子
  9. Android中的SurfaceTexture
  10. android sdcard的使用