Mar*_*uro 18 iphone bluetooth ios core-bluetooth bluetooth-lowenergy
我有一个应用需要检测运行相同应用程序和iOS 7.1的附近(蓝牙LE范围内)设备.我考虑了两种检测方法:
看来选项1是不可能的,因为:
方案2似乎要走了,但实施方面存在一些困难:
关于这一点,我有以下问题:
Mar*_*uro 21
我找到了一种方法让这项工作成为Core Bluetooth(选项2),程序大致如下:
CBAdvertisementDataLocalNameKey广告的工作原理如下:
[UAUtils deviceID],因为它也是程序其他部分的设备标识符 - 但你也可以使用任何唯一的ID实现).当应用程序正在运行的前景,我可以通过该设备唯一的ID 直接在通告报文,通过使用CBAdvertisementDataLocalNameKey.标准的UUID表示太长了,所以我使用UUID的缩写形式如下:
+ (NSString *)shortenedDeviceID
{
NSString *deviceID = [UAUtils deviceID];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:deviceID];
uuid_t uuidBytes;
[uuid getUUIDBytes:uuidBytes];
NSData *data = [NSData dataWithBytes:uuidBytes length:16];
NSString *base64 = [data base64EncodedStringWithOptions:0];
NSString *encoded = [[[base64
stringByReplacingOccurrencesOfString:@"/" withString:@"_"]
stringByReplacingOccurrencesOfString:@"+" withString:@"-"]
stringByReplacingOccurrencesOfString:@"=" withString:@""];
return encoded;
}
Run Code Online (Sandbox Code Playgroud)当应用程序运行后台时,广告数据包将被剥离,CBAdvertisementDataLocalNameKey不再传递.对于这一点,该应用程序需要发布一个特性,提供了唯一的设备标识符:
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
if (peripheral.state == CBPeripheralManagerStatePoweredOn) {
[self startAdvertising];
if (peripheralManager) {
CBUUID *serviceUUID = [CBUUID UUIDWithString:DEVICE_IDENTIFIER_SERVICE_UUID];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:DEVICE_IDENTIFIER_CHARACTERISTIC_UUID];
CBMutableCharacteristic *characteristic =
[[CBMutableCharacteristic alloc] initWithType:characteristicUUID
properties:CBCharacteristicPropertyRead
value:[[MyUtils shortenedDeviceID] dataUsingEncoding:NSUTF8StringEncoding]
permissions:CBAttributePermissionsReadable];
CBMutableService *service = [[CBMutableService alloc] initWithType:serviceUUID primary:YES];
service.characteristics = @[characteristic];
[peripheralManager addService:service];
}
}
}
Run Code Online (Sandbox Code Playgroud)扫描工作如下:
您开始使用特定服务UUID扫描外围设备,如下所示(请注意,您需要指定服务UUID,否则后台扫描无法找到设备):
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:DEVICE_IDENTIFIER_SERVICE_UUID]]
options:scanOptions];
Run Code Online (Sandbox Code Playgroud)当- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI您发现设备时,检查是否advertisementData[CBAdvertisementDataLocalNameKey]存在,并尝试将其转换回UUID表单,如下所示:
+ (NSString *)deviceIDfromShortenedDeviceID:(NSString *)shortenedDeviceID
{
if (!shortenedDeviceID)
return nil;
NSString *decoded = [[[shortenedDeviceID
stringByReplacingOccurrencesOfString:@"_" withString:@"/"]
stringByReplacingOccurrencesOfString:@"-" withString:@"+"]
stringByAppendingString:@"=="];
NSData *data = [[NSData alloc] initWithBase64EncodedString:decoded options:0];
if (!data)
return nil;
NSUUID *uuid = [[NSUUID alloc] initWithUUIDBytes:[data bytes]];
return uuid.UUIDString;
}
Run Code Online (Sandbox Code Playgroud)如果转换失败,你知道的广播设备是在后台,你需要连接到设备读取的特性,它提供的唯一标识符.为此,您需要使用[self.central connectPeripheral:peripheral options:nil];(使用peripheral.delegate = self;并实现一系列委托方法,如下所示:
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
[peripheral discoverServices:@[[CBUUID UUIDWithString:DEVICE_IDENTIFIER_SERVICE_UUID]]];
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (!error) {
for (CBService *service in peripheral.services) {
if ([service.UUID.UUIDString isEqualToString:DEVICE_IDENTIFIER_SERVICE_UUID]) {
NSLog(@"Service found with UUID: %@", service.UUID);
[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:DEVICE_IDENTIFIER_CHARACTERISTIC_UUID]] forService:service];
}
}
}
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (!error) {
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:DEVICE_IDENTIFIER_CHARACTERISTIC_UUID]]) {
[peripheral readValueForCharacteristic:characteristic];
}
}
}
}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (!error) {
NSString *shortenedDeviceID = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSString *deviceId = [MyUtils deviceIDfromShortenedDeviceID:shortenedDeviceID];
NSLog(@"Got device id: %@", deviceId);
}
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
7555 次 |
| 最近记录: |