蓝牙广播数据解析
从上一篇我们提到的那样我们从系统的接收到了 关于蓝牙数据的相关信息,蓝牙的设备对象、蓝牙信号、标准蓝牙广播数据包等数据。
==================================================================================================================
作为我们开发的场景来说,我们需要对我们的设备进行必要的过滤,但是这个过滤的数据来源除了广播数据包,好像是没有其他办法的。当然名字也还是那么靠谱的,会有系统的缓存的。
所以我们需要做一些蓝牙广播的数据的解析。说到蓝牙的数据的数据解析的问题,就不得不提关于蓝牙的数据结构,不过这个网上有很多,百度一下,出来的结果能吓死你,哈哈。毕竟度娘是厉害的。-------言归正传:
蓝牙的数据结构采用的方式。这有一篇文章还不错的推荐给大家
http://blog.chinaunix.net/uid-28852942-id-5176579.html
其实在我们android 开发的数据解析中 倒是没有说的那么复杂,比方来说,
0201060303f1fe03190000020a080aff0000000000000000041509efbbbfe5beaee699ba426561636f6ee6a0bc5a690
上方是一个蓝牙数据(这个数据是我随便弄得只是做为示范)
对于我们开发来说
我们知道这样的数据构成就OK了
- 020106
- 这是一个完全的“最小单元有意义的蓝牙广播数据”了吧。
- 02表示这个数据的长度,也就是Length.
- 01表示这个信息的标识,也就是Tag.
- 01后面开始就是这个数据含有真正的数据,
- 此时需要注意的是02表示长度是除去自身以外的长度, 如果你要数字节个数的话 你需要加1
0303f1fe
03190000
020a08
0a ff 00 00 00 00 00 00 00 00 04
15 09 efbbbfe5beaee699ba426561636
其他的都是一样的 我就不做一一解析了。
所以我们解析这个数据的时候都是解析相关的TAG,然后可以拿到我们需要的数据,我记得刚刚开始的时候,我是拿着这个数据直姐用索引取值,结果我们的固件版本一升级,索引值变了。我那个写死的数据就完蛋了。结果当然是教育了啦。
提一些的是关于常见的Tag,01一般表示是否可连接的状态。08、09一般都是可以表示设备的名称。但是也有很多是不广播名称的。
好吧BB那么多贴上源码才是关键以下是源码:
public static class BTScanInfo {
//数据库
public BleDevice dev;
public byte[] advt;
public double rssi = -10000.0;
public static final int
BT_ADVT_FIELD_SHORT_SVC_UUID_MORE = 0x02,
BT_ADVT_FIELD_SHORT_SVC_UUID_COMP = 0x03,
BT_ADVT_FIELD_MANU_INFO = 0xFF,
BT_ADVT_FIEFD_NAME_INFO = 0x09,
BT_ADVT_FIEFD_SUPPROTS_INFO = 0xFF;
public int svcMoreOffset = -1, svcMoreLen = -1,
svcOffset = -1, svcLen = -1, isSupprots = 14,
manuOffset = -1, manuLen = -1,
nameOffset = -1, nameLen = -1,
lightOffset = -1, lightLen = -1;
public BTScanInfo(BleDevice dev_, byte[] advt_, double rssi_) {
Log.i(dev_.getAddress(), "BtScanInfo==" + dev_.getAddress());
dev = dev_;
advt = advt_;
rssi = rssi_;
ParseAdvt();
}
public void ParseAdvt() {
if (advt == null)
return;
for (int offset = 0 ; offset < advt.length ; ) {
int fieldLen = (advt[ offset ] & 0xFF);
if (fieldLen < 1) {
offset += fieldLen + 1;
// Log.v(TAG, "Find a invalid scan advert field length: " + fieldLen );
continue;
}
// a valid field.
if (offset + fieldLen <= advt.length) {
int fieldType = advt[ offset + 1 ] & 0xFF;
if (fieldType == BT_ADVT_FIELD_SHORT_SVC_UUID_MORE) {
svcMoreOffset = offset;
svcMoreLen = fieldLen;
} else if (fieldType == BT_ADVT_FIELD_SHORT_SVC_UUID_COMP) {
svcOffset = offset;
svcLen = fieldLen;
} else if (fieldType == BT_ADVT_FIELD_MANU_INFO & fieldLen == BT_ADVT_FIEFD_NAME_INFO) {
manuOffset = offset;
manuLen = fieldLen;
} else if (fieldType == BT_ADVT_FIEFD_NAME_INFO) {
//获取到名字信息
nameOffset = offset;
nameLen = fieldLen;
}
}
offset += fieldLen + 1;
}
}