iOS开发蓝牙4.0初识

iOS开发蓝牙4.0初识
转载 2015-09-20 15:26:44
标签:ios开发蓝牙ios开发蓝牙4.0ios开发蓝牙连接ios开发蓝牙扫描ios蓝牙4.0

防丢自拍器

车载仪表盘

针灸仪设备

ANCS实现的监控来电,短信,邮箱

第一张图片防丢自拍器已经上传到APPSTORE,源码已经上传到QQ群共享460325065

要了解一项技术,最好先了解一下历史。1994年,爱立信一位工程师,为了解除日益增多的连接线缆的烦恼,发明了一种名为蓝牙的短距离无线通信技术。自2001年发布蓝牙1.1版本技术规范,一群诺基亚的工程师就开始畅想,在若干年后,如何让智能移动设备与周边的嵌入式设备连接的时间更长,从而使得智能移动设备成为与周边10m范围内各种电子产品通信的中枢。经过10年的努力,蓝牙技术联盟终于在2011年发布了里程碑版本的蓝牙4.0技术规范,其中最具吸引力的就是低功耗蓝牙技术规范。

      在无线技术迅猛发展的今天 ,蓝牙技术到底是一个什么位置,可以通过下图做一个简单的了解。

该图片摘自《BLE权威教程》,我新建了一个QQ群460325065,群共享上传了该文献
​目前市场上影响力最大的三种无线技术,蓝牙,WIFI和Zigbee。从上图可以看出,蓝牙的传输距离是最短的,功耗是高于Zigbee,低于WIFI。传输距离最短,只有2-10米,当然这是传统蓝牙,传输速度能达到3Mbps。如果用过诺基亚手机的人,应该知道,在那个没有智能手机的时代,已经有了蓝牙技术,而且还能用蓝牙在两个手机之间传输音乐和图片。如果细心的人应该会发现,如今的智能手机,比如两台iPhone之间,在设置中,是无法搜索到对方。这是为什么呢?简单的说,因为蓝牙4.0技术。

     什么是蓝牙 4.0 ?

该图片摘自《BLE权威教程》,我新建了一个QQ群460325065,群共享上传了该文献
​从上图我们可以发现,全新的蓝牙4.0技术并不是一种技术,而是由传统蓝牙,高速蓝牙和低功耗蓝牙合而为一。并且这三种蓝牙可以组合使用,也可以单独使用。其中,低功耗蓝牙即BLE是蓝牙4.0的核心规范。毫不夸张的说,蓝牙4.0为什么可以成为改变生活的原因,就是因为BLE,低功耗蓝牙的产生。因为一切智能设备,都需要电,电量用完,设备就是一堆废铁。然而,低功耗是硬件上的事情,跟我们手机APP有什么关系,APP根本就不关心你耗电不耗电,我只写我的客户端就好了啊。实际上,与APP还是有关系的,正是因为有BLE和传统蓝牙,市场上是有三类蓝牙产品的。如果你不知道你在为哪一类产品开发程序,你会遇到很多麻烦,比如说,老板要你用BLE传输音频数据,如果你不知道传音频是传统蓝牙的功能,你可能会白辛苦很久而达不到效果。在举个例子,如果老板要你监控来电短信或者邮件等其他信息,然后通过APP发送到蓝牙设备。如果你不知道这是ANCS的工作,而自己傻傻的去找检测来电短信的办法,然后还要在程序退到后台依然能起作用,并通过BLE发送到设备,那可能你的工作中会充满烦恼。到最后还认为你的水平很low。

所以,作为iOS工程师,第一件事情,就是要区分你正在开发的APP是为单模蓝牙,还是双模蓝牙;仅传统蓝牙是不需要APP的,譬如市面上大多数的蓝牙音箱,只要连上电脑或者手机,在电脑或者手机设备上播放音乐,系统底层就可以通过传统蓝牙协议,将音频数据传到蓝牙音箱上播放。换句话说,就是传统蓝牙部分在APP上不可控,在iOS上,更是连判断在设置中是否连接了传统蓝牙都办不到,iOS可控的部分只有BLE。那为什么还要区分单模,双模呢,知道又如何,传统蓝牙部分都无法控制,原因在哪?答案在于这里说的不可控,是指在iOS上,但是在硬件上是可以知道的。我们可以通过BLE将传统蓝牙的连接状态,以及一些其他信息指定一套协议进行沟通。当然,如果你想要实现像苹果手表那样的功能,在手机上有来电和短信,或者其他软件信息提醒的时候,在你的蓝牙设备上也能接收到。那这个功能的实现需要用到ANCS(Apple Notification Center Service)。ANCS在可以看成一个超级权限,但却跟传统蓝牙工作在不同局域,一个是通知,一个是音频。具体的实现,我们都不得而知,这部分属于苹果系统的功能了。从我上上个月开发过的那个ANCS产品来看,我个人的感觉ANCS目前存在一些BUG,ANCS的产品在BLE操作中,会出现断开不了的情况,所以从这点上看,感觉ANCS是有一些BLE的成分。而从这个协议单纯的理解,应该要像传统蓝牙一样,一个单独连接,与BLE无关才对;但是ANCS没有像传统蓝牙一样在设置中有一个专栏;所以,感觉从目前来说,貌似有BUG,也许目前已经解决,只是我不知道。

从上图,我们还应该知道的是,并不是所有手机都支持蓝牙4.0技术,iPhone需要4S以上的手机,安卓需要系统4.3及以上的版本。

到这里,大家应该对市面上的蓝牙设备有一个大概的分类了,那如何区分,也说了 ,在iOS上区分一个设备是否包含传统蓝牙的​方法是通过查看设置中是否有传统蓝牙的连接。因为苹果系统对用户隐私的保护,传统蓝牙的连接,在第一次连接时,用户必须自己手动点击连接。后面可以通过设备在手机打开蓝牙时自动连接。ANCS会在启动时,在程序中有提示,而且这个提示框是无法去掉的。而在BLE中,有时候也会出现提示框,而这个提示框,可以在硬件上去掉。判断BLE的方法,就是第三方APP与蓝牙设备通信,就一定是BLE的功能了。据硬件工程师的说法,ANCS是涵盖BLE和传统蓝牙功能的。而我在测试的过程中,ANCS会在手机上弹出连接的窗口,而一旦连上,BLE的连接会受到ANCS的影响。但是在BLE断开的情况下,ANCS依然可用。由于没办法看到ANCS是否正常,所以也不好下结论,所以我说,也许存在BUG,所以这篇博客的名字叫蓝牙4.0初识。

一般来说,从一个技术博客的角度出发,写一篇博客的话,应该是大多数的代码,而这篇我写这么多不是代码的东西,实际上,在真正的蓝牙开发过程中,如果不了解这些,会产生很多疑惑,因为,从iOS蓝牙开发角度说,苹果已经帮我们把底层都封装起来了,我们只是简单的调用,毫不夸张的说,一个半年的新手都能在两天之内上手,一个星期内使用。然而,并不是说你能用就能解释清楚其中的很多状况。从我个人来说,我是喜欢弄明白一个现象深处的东西。而弄清楚最好的办法,就是深入了解蓝牙4.0的方方面面。

在了解蓝牙的历史,什么是蓝牙4.0,蓝牙产品的分类,各类产品能实现什么功能,以及如何为你的需求做蓝牙技术上的选择之后,下面讨论的是蓝牙连接的问题。

蓝牙4.0连接​中的一些小知识

说到连接,不得不重提之前两台iPhone手机在设置中无法发现发现对方的问题,两台设备,要相互知道对方,唯一的办法,只能是至少有一个人告诉对方,我是谁。如果两台设备都不说话,那肯定不知道对方是蓝牙设备的身份。所以,蓝牙连接的过程,实际上就是一个沟通的过程,在蓝牙设备中,说话是通过广播一段无线信号实现,一台蓝牙设备是不能同时广播和接收广播,因为目前芯片还没那么强大。在蓝牙通信中,接收广播的那个设备叫主机(Central),发送广播的设备叫从机(Peripheral)。而通常手机都处在主机状态,也就是只能接收广播,而自己没有向周围发送广播。所以两台手机之间一般是无法发现对方的。除非,你写一段程序,让手机向周围发送广播。目前,作为主机的设备,是可以与多个从机进行连接的,而作为从机的设备,通常只能与一个主机进行连接,通常在与一个主机相连后,设备就会关闭广播。所以,在开发过程中,可能你的身边有多个蓝牙设备处于运行状态,但是一个也搜索不到,那就是因为别人的手机已经连接了。然而,在蓝牙设备上,并不是在连接之后就必须关闭广播,是可以在芯片上实现让他继续广播的。那是不是就能说明一台从机就可以连接多台主机呢?目前答案是不行。因为目前市场上,影响最大的是美国TI公司的CC2540/CC2541,以及新出来的CC2640/CC2650系列产品,目前没有实现他作为从机时,多连的功能。从另一个角度说,主机能连接多个,从机也连接多台设备,通信协议无疑会变得很复杂,从机发数据到底发给谁,怎么去控制他发送。单这两个问题,就决定了蓝牙设备作为从机时,只能连接一个主机。作为主机的设备,采用蓝牙4.0协议的话,也不是连接任意台设备的,经过测试,iPhone手机最多能连10台从机,安卓手机得看手机性能,6到10台不等。如果要连接更多的设备,在蓝牙4.1;4.2中,蓝牙联盟已经在改进蓝牙协议了。那实现这一点,就需要你的手机和你的蓝牙设备里的芯片都支持到蓝牙4.1,4.2,那无疑对手机的要求更高,用户群更小,而市场上支持4.1和4.1蓝牙协议的芯片并不多,即使有也在试验阶段,不一定稳定。而10个的连接数,已经能满足大多数用户的需求了,新的芯片成本肯定更高,所以在选择支持4.1或4.2协议时,慎重。(小秘密:在做安卓测试的时候,在京东上买了多台手机,然后7天无理由退货,又退回去,自己只需要一些快递费)

该图片摘自《蓝牙4.0 BLE开发完全手册 物联网开发技术实战》,我新建了一个QQ群460325065,群共享上传了该文献
如果做过蓝牙开发的人应该都知道,连接蓝牙并不是百分百成功的,很可能你连上之后秒断,仿佛没有连接一样。并不是程序写的有问题,APP上确实会发生这样的事情。根本原因在于底层蓝牙协议。

​上图就是蓝牙4.0BLE协议栈,对于iOS开发人员来说,你也可以完全不用管它,但是做过安卓的同学肯定知道GATT服务器。它位于整个协议栈的最高层,与APP进行交互。在安卓开发过程中,代码可以明确的知道APP上的BLE连接是委托GATT服务器完成的。而在iOS上,就是蓝牙管理中心CBCentralManager。苹果已经把底层都封装起来了,这可以说是做iOS的幸福之处,也可以说是对开发者的不幸之处,因为完全不清楚为什么会这样。

GATT服务器才是真正决定连接是否成功的关键。GATT在收到连接请求后,会像下继续请求资源,而由于蓝牙资源是有限的,所以并不是每一次请求都会成功,特别当你实现多连的时候,连接的越多,越容易出现连接断开的情况。

还有一个原因,两个设备之间是如何确定对方还处于连接状态的呢,也是类似于一个心跳包的概念。上图中的“有效连接间隔”。

☆短间隔的连接事件:两设备都会以高能耗运行,高数据吞吐量,发送等到时间短

☆长间隔的连接事件:两设备都会以低能耗运行,低数据吞吐量,发送等待时间长

如果连接过程经常断开,可以尝试将硬件的连接时间间隔​缩短。当然有利有弊。

​那对于这个问题,在软件怎么解决?实际上没法从根本上解决,只能多连几次,可以在蓝牙4.0断开时自动重连。

蓝牙的东西太多,一篇文章肯定讲不清楚。篇幅过长会看的疲劳,下面讲一下CODING。

​第二部分:XCODE中的操作
一.一个简单的demo搭建​

1.用xcode建立一个project,建一个Single View Application​,给项目取个名字BleTest,我选的语言是OC。

2.​在ViewController.h头文件中加入#import "CoreBluetooth/CoreBluetooth.h"这个头文件,两个委托方法<</span>CBCentralManagerDelegate,CBPeripheralDelegate>,声明一个变量@property (strong,nonatomic) CBCentralManager * MyCentralManager;

3.​在ViewController.m的viewDidLoad方法中加入self.MyCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];​

4.在ViewController.m方法体中加入如下两个方法

pragma mark - Navigation

  • (void)centralManagerDidUpdateState:(CBCentralManager *)central

{

switch (central.state) {

    case CBCentralManagerStateUnknown:

        break;

    case CBCentralManagerStateUnsupported:

        NSLog(@"模拟器不支持蓝牙调试");

        break;

    case CBCentralManagerStateUnauthorized:

        break;

    case CBCentralManagerStatePoweredOff:

        NSLog(@"蓝牙处于关闭状态");

        break;

    case CBCentralManagerStateResetting:

        break;

    case CBCentralManagerStatePoweredOn:

​ NSLog(@"蓝牙已开启");

      [self.MyCentralManager  scanForPeripheralsWithServices:nil  options:nil];​

        break;

}

}

  • (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

{

NSLog(@"能发现设备:%@",peripheral.name);

}

​5.运行程序,一个最简单的蓝牙程序就完成了

如何手机设备的蓝牙已打开,在LOG消息中可以看到附近的蓝牙设备。蓝牙不支持模拟器调试,必须使用iPhone4S以上的真机调试。

二.实现更多功能​

1.​CBCentralManager主设管理中心,需要且必须是单例。一个程序中只能有一处,如果有两处,并不能同时在两处连接。我曾试过,最多只能在两处扫描到设备。道理很简单,在手机上,蓝牙就跟相机一样都只有一个,能同时实现两个摄像头拍照吗,不能。如何解决,只能在程序中继承,传递主设对象或建一个全局变量。self.MyCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];对于这个方法,第一个参数没得说,你非要赋值为nil也可以的,再用self.MyCentralManager.delegate=self;也可以实现。第二个参数,If the value is nil, the central manager dispatches central role events using the main queue.如果设置为nil,默认在主线程中跑。

2.​CBCentralManagerDelegate委托方法,必须要实现的一个方法,- (void)centralManagerDidUpdateState:(CBCentralManager *)central用于检测当前设备的蓝牙状态。而我通常喜欢在CBCentralManagerStatePoweredOn蓝牙开启时才开始扫描。

3.扫描的方法是[self.MyCentralManager scanForPeripheralsWithServices:nil options:nil];​这里两个参数都是nil,也可以不用nil,那这两个参数是什么意思呢?第一个参数是指,扫描指定的服务(Services)。第二个参数是扫描过程中的一些设置。服务是什么?打个比方,如果你需要到银行取钱,第一步,你需要找到银行的网点,第二步,找一个柜台的服务员。找到网点并不能进行存钱取钱操作,但是必须找到网点,才能找到服务员,而存钱取钱操作必须在网点内进行才被允许。对应到蓝牙上,服务员就是特性(characteristic),如果要进行数据的交互,只能对特性进行。一个蓝牙设备,可能有多个服务,如果你只需要扫描指定的服务,就可以指定第一个参数。第二个参数,可以有很多其他设置。

停止扫描的方法[self.MyCentralManager stopScan];这个方法,通常会在重新搜索附近蓝牙设备的时候用到。

实现重新扫描​,将委托再指定一次。停止扫描,同时移除数组中所有到的扫描,再开启扫描。通常,在扫描到某一个设备后,都加入到一个数组中,以便进行连接。

-(void)seachAction{
// NSLog(@“重新搜索");
self.cbCentralMgr.delegate=self;
[self.cbCentralMgr stopScan];

if (dataArray.count) {
    [dataArray removeAllObjects];
}

NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[self.cbCentralMgr scanForPeripheralsWithServices:nil options:dic];

}
4.扫描中的设置参数:如果第二个参数为nil,扫描到设备的次数一般为两次,就是- (void)centralManager: didDiscoverPeripheral: advertisementData: RSSI:执行的次数为两次。而对于一些特殊的APP,如蓝牙称或者通过广播辨别设备状态时,需要实时接收广播数据。那可以用CBCentralManagerScanOptionAllowDuplicatesKey,代码为:

NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],CBCentralManagerScanOptionAllowDuplicatesKey, nil];

[self.MyCentralManager scanForPeripheralsWithServices:nil options:dic];

CBCentralManagerScanOptionSolicitedServiceUUIDsKey

An array (an instance of NSArray) of service UUIDs (represented by CBUUID objects) that you want to scan for.Specifying this scan option causes the central manager to also scan for peripherals soliciting any of the services contained in the array.这是苹果的说明,简单说就是给一个数组,然后扫描指定数组中的服务,这个方法跟scanForPeripheralsWithServices的第一个参数一样的功能。而扫描只有CBCentralManagerScanOptionAllowDuplicatesKey和CBCentralManagerScanOptionSolicitedServiceUUIDsKey两个参数可以选择。比较有用的是第一个。

5.连接的方法 [self.MyCentralManager connectPeripheral:peripheral options:nil];如果连接成功建立,则会调用centralManager:didConnectPeripheral:回调方法,如果连接建立失败,则调用 centralManager:didFailToConnectPeripheral:error:方法。这个连接的方法会一直执行。如何实现自动断线重连,就是在断开的委托方法中,执行连接蓝牙的方法。由于蓝牙的有效距离在10米,当手机离开蓝牙设备10米范围之后,手机可能会失去连接,而有些情况下,需要手机在回到10范围内的时候自动连接。那我们只需要在断开连接的时候,执行连接操作,因为蓝牙会一直处于尝试连接指定蓝牙的操作,没有时间限制。但如果当蓝牙对象被释放后,潜在的蓝牙连接尝试操作也会被取消掉。第一个参数,连接的蓝牙对象,没什么说的;第二个参数,可以有三种:CBConnectPeripheralOptionNotifyOnConnectionKey,CBConnectPeripheralOptionNotifyOnDisconnectionKey和CBConnectPeripheralOptionNotifyOnNotificationKey这三种参数的用处在于没有使用background mode​的时候是否显示Alert提醒信息,三种参数如果不做任何设置,都默认为NO,第一种参数OnConnectionKey在程序被挂起时,连接成功显示Alert提醒框,第二种参数,OnDisconnectionKey在程序被挂起时,断开连接显示Alert提醒框,第三种参数,OnNotificationKey在程序被挂起时,显示所有的提醒消息。

断开连接的方法[self.MyCentralManager​ cancelPeripheralConnection:peripheral];这个方法会取消已经连接成功的蓝牙,也会取消正在连接中的蓝牙。这个方法并不是使用的块方法,当执行断开连接之后继续对这个蓝牙对象进行操作指令,这个操作指令也许能完成,也许不能。因为很有可能其他app可能仍然保持着对这个蓝牙的连接,断开本地的蓝牙连接并不能保证潜在的物理连接会立刻断开,但是从app的角度看,会认为蓝牙是立刻断开了的,而且蓝牙主设管理中心也会立刻执行这个委托方法centralManager:didDisconnectPeripheral:error:。所以在理论上,iOS设备是可以同时连接10个蓝牙设备的,但是当之前的连接断开之后,并不能在物理层保证蓝牙已经断开连接,所以有时候会发生,连接数还没达到10个,蓝牙就死掉的情况。​

6.​- retrieveConnectedPeripheralsWithServices:根据制定的服务,找到当前系统处于连接状态的蓝牙中包含这个服务的所有蓝牙对象。- retrievePeripheralsWithIdentifiers:根据UUID找到所有匹配的蓝牙对象。

7.发送数据​- (void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic type:(CBCharacteristicWriteType)type;通常我会使用下面的写法,遍历整个服务,找到通信需要的特性,当然,如果做过多种蓝牙的同学应该会知道,这个函数的最后一个参数,可能有两种,如果你的程序出现连接正常,而你确定执行了写数据的函数,但是硬件确实没有反应,那很有可能是你的CBCharacteristicWriteType不对,需要使用另一种,一共是两种CBCharacteristicWriteWithResponse和CBCharacteristicWriteWithoutResponse,一般写IC程序的开发人员都是使用一个叫LightBlue的APP,用这个APP可以看到蓝牙设备的服务,特性,以及读写类型。

for (CBCharacteristic *characteristic in [[peripheral.services objectAtIndex:i] characteristics])​

{ if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:UUID_FFF6]])

{        [self.peripheralOpration writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];

}

}​

而如果主设备要接收来自从机的数据的话,需要给从机一个权限,而且还要指定特性​,[peripheral setNotifyValue:YES forCharacteristic:characteristic];这样的话,从机就可以通过参数中的characteristic特性传数据到主机,而主机响应的方式是通过-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error这个委托方法。

8,多个蓝牙对象时,如何管理,可以将蓝牙对象看成简单的字典对象。在要求与多个蓝牙设备同时通信时,逐个进行操作。有时候会产生分组的概念,而区分出每个蓝牙对象不同的方法就是蓝牙设备的UUID,UUID在每个手机设备上​生成的都不一样,不同的蓝牙设备,在同一台手机上也不一样。因为UUID是由唯一的MAC地址和手机的识别码一起通过一个加密算法得到。目前市场上,出货比较大的是蓝牙灯,很多蓝牙灯均有房间,和分组的概念,所以这一点也比较有用。

9.如何实时获取RRSI值,当未连接的时候,可以设置一直接收广播信息,方法看上面第3个知识点,在- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI的最后一个参数中就是RRSI值。如果对于已连接的设备,也需要实时检测RRSI值,例如目前市场上大多数的蓝牙防丢器或其他蓝牙防丢设备,现在只能在程序中写一个计时器,隔一定时间间隔,去获取

-(void)ShowRSSI{
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(_timer, ^{
if(timeout<=0){ //倒计时结束,关闭
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
//设置界面的按钮显示 根据自己需求设置
// NSLog(@"--");
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
if (bleConnectViewContrller.peripheralOpration.state==2) {
if (IS_IOS_8) {
[bleConnectViewContrller.peripheralOpration readRSSI];
}else{
// NSLog(@"%@",[NSString stringWithFormat:@"%@",[bleConnectViewContrller.peripheralOpration RSSI]]);
}
}else{
// NSLog(@"--");
}
});
timeout--;
}
});
dispatch_resume(_timer);
}

10.关于将iPhone作为从机,像周围发送广播的用法,实际上这种需求比较少,通常手机都是主机,这里不做论述,如有需要可以提供demo。
11.通常蓝牙设备会在连接设备之后,会去发现设备的服务和特性,甚至很多设备在连接成功的时候都会对设备做一个初始命令的设置,譬如蓝牙灯泡在刚连上时,将灯泡亮度调到最大。而有的APP会有自动重连功能,那在程序启动的时候就会发生周围多个设备,并连接,寻找服务特性,并发送数据。我想说的是,这个时候如果程序中有重新搜索功能的话,会出现bug。之前讲到过,蓝牙连接执行了断开方法后,并不能立即在物理连接上断开。所以通常,不要将自动重连和重新搜索功能放在一起。

如果需要知道文章中文献的,可以到QQ群460325065下载。

9月22号收到第一个质疑,连接个数,我写的最多10个,有人说可以超过这个数,百度了一下,没有找到直接证明可以超过10个的证据。实际上,蓝牙协议并没有规定上限,理论上可以连接无数个。但是在手机主设端做不到,一个原因为主设的蓝牙资源有限;二个是因为连接的个数越多,手机需要跟所有设备保持连接,需要逐个轮训,发送连接存在的消息。而苹果上也对蓝牙发送时间间隔做了一个设定。所以目前来说,连接个数终有上限。超过10个的限制也是时间问题,但是具体一台手机能连多少个从机,就需要针对自己的产品做详细测试了。也许有其他非TI厂家生产的芯片,可以做到超过10个。

有朋友说运行程序没有任何反应,是因为附近根本就没有蓝牙设备,如果没有蓝牙设备,也可以通过两台iPhone或者iPad将其中一个设为从机进行测试。​

有朋友问到iOS中HFP开发​,通过蓝牙设备实现打电话的功能。这个功能确实能实现,但是跟iOS APP关系不大,完全由蓝牙设备配合系统协议实现的。APP端只能对BLE操作,如果要录下通话内容,只能在开始通话时,让蓝牙设备传一个信号到iPhone上,开始录音;在通话结束时,再传一个信号到手机,结束录音。

推荐阅读更多精彩内容