iOS-蓝牙项目经验总结(上)

蓝牙开发中碰到的几个技术点:

0),蓝牙协议制定;  

1),蓝牙密钥配对;

2),获取蓝牙Mac地址;

3),实时获取蓝牙设备信号;

4),通过蓝牙升级硬件版本;

5),通过蓝牙上传文件;

6),封装蓝牙静态包;


蓝牙协议制定:

蓝牙封包格式依次为:包头(一个字节),指令码(一个字节),封包长度(一个字节),参数(n个字节),校验码(一个字节);

例如下图:

当然还有封包格式更简单的,只有包头,指令码,和参数组成;具体什么格式要找硬件开发人员定义,蓝牙以二进制的数据流,通过广播发送至app端, app在回调方中接收的数据为NSData类型。(接收数据处理:NSData -> byte ->NSString).

包头:是硬件返回指令包首个字节的内容,可以与硬件开发人员定义好。

指令码:是区分每个指令的内容,可以与硬件开发人员定义好。

长度:封包總長度(包含包頭、校驗碼),單位為byte。

参数:依指令碼不同而定。

校验码:Checksum , 封包中除了校驗碼以外的位元組數據總和,再除以256的餘數。

蓝牙密钥配对:

蓝牙配对分为LMP配对(PIN配对)和SSP配对,前者需要输入pin码进行蓝牙配对。后者不需要输入pin码。其中具体的原理参照如下链接:https://www.jianshu.com/p/683c287fee3e。

在这里,大家普遍踩过的坑,就是配对警告框不弹出的问题。解决办法:1),要和硬件开发人员确定蓝牙设备是否发送配对广播,这个可以让硬件开发人员确定,他们手里都有蓝牙厂商提供的相应的测试app。2),最容易忽略的一点,就是代码中在初始化蓝牙中心设备和搜索蓝牙设备的时候设置options参数为@{CBCentralManagerOptionShowPowerAlertKey:@YES}。{CBCentralManagerOptionShowPowerAlertKey:@(YES)} 允许弹出警告框。  具体代码如下:

        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey:@(YES)}];

    [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerOptionShowPowerAlertKey:@(YES)}];。

获取蓝牙Mac地址:

由于苹果手机的保密性,蓝牙设备通过广播携带的私有蓝牙信息会被屏蔽掉。不过还有些项目在链接蓝牙设备时,会用到蓝牙的Mac地址 蓝牙Mac地址。此时就需要获取蓝牙的Mac地址。解决办法如下:

1),不要让硬件开发人员把Mac地址写在广播字段中,应该以参数的形式添加到Advertising Packet 中(我向硬件开发人员请教了一下,官方语言:Added the mac address in Advertising Packet),传过来。iOS在 一下回调方法中解析advertisementData参数即可得到

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber*)RSSI 

解析代码,如下

     

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber*)RSSI 

{

        NSData* advertisementData = [advertisementData objectForKey:@"kCBAdvDataManufacturerData"]; //解析Mac地址, kCBAdvDataManufacturerData为advertisementData中的key值。其对应的value即为Mac地址。

        NSString *value = [self hexadecimalString:advertisementData];    //获取Mac地址

}   

-(NSString *)hexadecimalString:(NSData *)data{                                                                                                                                           

 NSString *result;

  const unsigned char *dataBuffer = (const unsigned char *)[data bytes]; 

if (!dataBuffer) {return nil;}NSUInteger dataLength = [data length];

NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; 

for (int i = 0; i<dataLength; i++) {  

//02x 表示两个位置 显示的16进制

 [hexString appendString:[NSString stringWithFormat:@"%02lx",(unsigned long)dataBuffer[i]]];  

}  

 result = [NSString stringWithString:hexString]; 

 if (result.length < 4) {        

    return @"0000"; 

   }

result = [result substringFromIndex:4];   

 return result; 

}

实时获取蓝牙设备信号:

此坑比较隐蔽,按正常蓝牙扫描链接的正常流程走,是不能实时获取蓝牙设备信号的,纵观苹果官方暴漏的蓝牙API中,只有方法 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber*)RSSI 中的参数RSSI能解析出蓝牙信号。但是为节省系统资源,一般的做法是,一旦调用上述方法获取到相应的蓝牙设备并链接成功蓝牙后,就调用[self.centralManager stopScan]; 停止扫描。此时self.centralManager的isScaning的属性为false。此方法就不再调用。也就意味着,蓝牙设备信号,在发现蓝牙设备的时候,只能获取到一次。那么怎么才能做到事实获取信号呢?当然是在链接成功蓝牙后不要调用[self.centralManager stopScan]; 

方法 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber*)RSSI就会一直回调,那么在此方法中解析出来你想要的蓝牙设备信号,展示在View上就OK了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容