iOS 蓝牙连接获取MAC地址的方法
iOS自从7以后就无法从API直接获取设备的MAC地址,只能用UUID来标识设备,要注意的是同一个设备在不同手机上显示的UUID不相同
解决办法
1:把它加到蓝牙的广播包里,但是这样的话对硬件来说负担很大 而且芯片会不稳定
2:有的设备可以通过 “180A”这个服务来发现特征,再来读取 “2A23”这个特征值,可以获得Mac地址(如果你的蓝牙设备不支持这样获取,你可以跟硬件工程师沟通,来获得Mac地址,添加一个获取地址命令或者增加一个含地址的特征值都可以很容易的获取)
这里着重介绍方法二:
1:蓝牙连接的流程
a.建立中心设备管理者
b.扫描外设
c.连接外设
d.扫描外设中的服务
e.扫描外设中的特征
f.订阅或读取特征值
g.获取外设中的数据
a:建立中心设备管理者
// 创建之后会马上检查蓝牙的状态,nil默认为主线程
self.centralManager = [[CBCentralManager alloc] initWithDelegate:selfqueue:nil]
b:扫描外设
// 蓝牙状态发生改变,这个方法一定要实现
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
// 蓝牙状态可用
if (central.state == CBCentralManagerStatePoweredOn) {
// 如果蓝牙支持后台模式,一定要指定服务,否则在后台断开连接不上,如果不支持,可设为nil, option里的CBCentralManagerScanOptionAllowDuplicatesKey默认为NO, 如果设置为YES,允许搜索到重名,会很耗电
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:nil]; }}
c.连接外设
/**
* 发现设备
* @param peripheral 设备
* @param advertisementData 广播内容
* @param RSSI 信号强度
*/- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber*)RSSI{
// 判断是否是你需要连接的设备
if([peripheral.name isEqualToString:kPeripheralName]) {
peripheral.delegate =self;
// 一定要记得把外设保存起来
self.selectedPeripheral = peripheral;
// 开始连接设备
[self.centralManager connectPeripheral:self.selectedPeripheral options:nil]; }}
d.扫描外设中的服务
/**
* 已经连接上设备
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
// 停止扫描
[self.centralManager stopScan];
// 发现服务
[self.selectedPeripheral discoverServices:nil];
}
e.扫描外设中的特征
/**
* 已经发现服务
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError*)error{for(CBService *serviceinperipheral.services) {
if([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) {
// 根据你要的那个服务去发现特性
[self.selectedPeripheral discoverCharacteristics:nilforService:service];
}
// 这里我是根据 180A 用来获取Mac地址,没什么实际作用,可删掉
if([service.UUID isEqual:[CBUUID UUIDWithString:@"180A"]]) { [self.selectedPeripheral discoverCharacteristics:nilforService:service];
}
}}
f.订阅或读取特征值
/**
* 已经发现特性
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError*)error{
for(CBCharacteristic *characteristicinservice.characteristics) {
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"2A23"]]) {
// 这里是读取Mac地址, 可不要, 数据固定, 用readValueForCharacteristic, 不用setNotifyValue:setNotifyValue
[self.selectedPeripheral readValueForCharacteristic:characteristic];
}
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) {
// 订阅特性,当数据频繁改变时,一般用它, 不用readValueForCharacteristic
[peripheral setNotifyValue:YESforCharacteristic:characteristic];
}
g.获取外设中的数据
/**
* 数据更新的回调
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError*)error{
//获取mac地址
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"2A23"]]){ NSString*value = [NSString stringWithFormat:@"%@",characteristic.value]; NSMutableString*macString = [[NSMutableString alloc]init];
[macString appendString:[[value substringWithRange:NSMakeRange(16,2)]uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(14,2)]uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(12,2)]uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(5,2)]uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(3,2)]uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(1,2)]uppercaseString]];
NSLog(@"MAC地址是macString:%@",macString); }
//这里写其他的BLE接收参数处理方法
}
设备连接断开
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError*)error{
// 让它自动重连
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:nil];}
这是系统代理方法,如果要主动断开需要调用
- (void)cancelPeripheralConnection:(CBPeripheral *)peripheral;这个方法
写入数据成功的回调
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError*)error{
// 读取数据
[self.selectedPeripheral readValueForCharacteristic:characteristic];}
原文连接:https://www.jianshu.com/p/0ccfd53fc559