CoreBluetooth框架:如何在不知道服务ID的情况下获取连接的设备?

时间:2015-05-26 06:14:31

标签: ios bluetooth core-bluetooth

我有一个蓝牙手环,通过蓝牙连接到我的iPhone 5s;它附带一个名为Zeroner的应用程序。现在我想在不使用App的情况下从连接和配对手镯中获取信息。这是我试图做的事情:

  1. 设置CBCentralManager
  2. 使用retrieveConnectedPeripheralsWithServices:获取已连接的设备
  3. 以下是代码:

    CBConnectedDevicesVC.h

    #import <UIKit/UIKit.h>
    #import <CoreBluetooth/CoreBluetooth.h>
    #import SERVICE_ID @"FB694B90-F49E-4597-8306-171BBA78F846"
    
    @interface CBConnectedDevicesVC : UIViewController <CBCentralManagerDelegate, CBPeripheralDelegate>
    
    @property (strong, nonatomic) CBCentralManager *centralManager;
    @property (strong, nonatomic) CBPeripheral *discoveredPeripheral;
    
    @end
    

    CBConnectedDevicesVC.m

    #import "CBConnectedDevicesVC.h"
    
    @implementation CBConnectedDevicesVC
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
    
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central {
        if (central.state != CBCentralManagerStatePoweredOn) {
            return;
        }
    
        if (central.state == CBCentralManagerStatePoweredOn) {
            NSArray* connectedDevices = [_centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:SERVICE_UUID]]];
            for (CBUUID *uuid in connectedDevices) {
                NSLog(@"Device Found. UUID = %@", uuid);
            }
        }
    }
    
    @end
    

    对于上面的代码,我必须在SERVICE_UUID中指定服务ID,我不知道手镯的价值是多少。有没有其他方法可以从连接的手镯中获取信息?

    更新关于LightBlue App的测试结果

    在Zeroner App取消配对并在“设置”&gt;中“忘记此设备”后蓝牙&gt;选择名为“Bracelet-0366”的设备,LightBlue App发现设备(最后!)。

    以下是结果截图:

    LightBlue screenshot

    我在这里得到了几个值,但我不确定应该使用哪些值。

    进一步的测试结果:

    如果我将LightBlue中的UUID(以4EFF开头)放入SERVICE_ID,则不会使用上述代码调用委托。

    我尝试的另一段代码是(从Tut+ tutorial获得):

    NSArray *serviceID;
    
    @implementation CBCentralManagerViewController
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        serviceID = @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]];
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
        _data = [[NSMutableData alloc] init];
    }
    
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central {
        // You should test all scenarios
        if (central.state != CBCentralManagerStatePoweredOn) {
            return;
        }
    
        if (central.state == CBCentralManagerStatePoweredOn) {
            // Scan for devices
            [_centralManager scanForPeripheralsWithServices:serviceID options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
            NSLog(@"Scanning started");
        }
    }
    
    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    
        NSLog(@"Discovered %@ at %@", peripheral.name, RSSI);
    
        if (_discoveredPeripheral != peripheral) {
            // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it
            _discoveredPeripheral = peripheral;
    
            // And connect
            NSLog(@"Connecting to peripheral %@", peripheral);
            [_centralManager connectPeripheral:peripheral options:nil];
        }
    }
    
    - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
        NSLog(@"Failed to connect");
        [self cleanup];
    }
    
    - (void)cleanup {
    
        // See if we are subscribed to a characteristic on the peripheral
        if (_discoveredPeripheral.services != nil) {
            for (CBService *service in _discoveredPeripheral.services) {
                if (service.characteristics != nil) {
                    for (CBCharacteristic *characteristic in service.characteristics) {
                        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
                            if (characteristic.isNotifying) {
                                [_discoveredPeripheral setNotifyValue:NO forCharacteristic:characteristic];
                                return;
                            }
                        }
                    }
                }
            }
        }
    
        [_centralManager cancelPeripheralConnection:_discoveredPeripheral];
    }
    
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
        NSLog(@"Connected");
    
        [_centralManager stopScan];
        NSLog(@"Scanning stopped");
    
        [_data setLength:0];
    
        peripheral.delegate = self;
    
        [peripheral discoverServices:serviceID];
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
        if (error) {
            [self cleanup];
            return;
        }
    
        for (CBService *service in peripheral.services) {
            [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]] forService:service];
        }
        // Discover other characteristics
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
        if (error) {
            [self cleanup];
            return;
        }
    
        for (CBCharacteristic *characteristic in service.characteristics) {
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
        }
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
        if (error) {
            NSLog(@"Error");
            return;
        }
    
        NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
    
        // Have we got everything we need?
        if ([stringFromData isEqualToString:@"EOM"]) {
    
            [_textview setText:[[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding]];
    
            [peripheral setNotifyValue:NO forCharacteristic:characteristic];
    
            [_centralManager cancelPeripheralConnection:peripheral];
        }
    
        [_data appendData:characteristic.value];
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    
        if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
            return;
        }
    
        if (characteristic.isNotifying) {
            NSLog(@"Notification began on %@", characteristic);
        } else {
            // Notification has stopped
            [_centralManager cancelPeripheralConnection:peripheral];
        }
    }
    
    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
        _discoveredPeripheral = nil;
    
        //
        [_centralManager scanForPeripheralsWithServices:serviceID options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
    }
    

    使用上面的代码,有2个常量定义为TRANSFER_SERVICE_IDTRANSFER_CHARACTERISTIC_ID。在本教程中,TRANSFER_SERVICE_ID应设置为以4EFF开头的TRANSFER_CHARACTERISTIC_ID0xFF20应设置为FF20location ~ ^/(assets/|images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) { root /var/www/analytics/web/; access_log off; expires 24h; } 。然而,这条代码根本没有检测到手镯,即使手镯是不配对的&amp;断开。这次我错过了什么?

2 个答案:

答案 0 :(得分:3)

不要担心以4EFF开头的UUID - 这是设备的UUID,每个设备的UUID都不同。

服务ID为FF20 - 您可以在scanForPeripheralsWithServices中使用此功能 - 在上面的代码中为SERVICE_ID

然后您有两个特征 - FF21FF22

您可以使用FF21实例上的writeValue方法写信至CBPeripheral

使用FF22,您可以使用setNotify CBPeripheral方法订阅通知。只要设备更改了值,您就会调用didUpdateValueForCharacteristic CBPeripheralDelegate方法。

答案 1 :(得分:2)

您可以使用两种类型的蓝牙设备:

  • BLE 设备 - 无需(通常无法)与iPhone配对
  • &#34;标准&#34;蓝牙设备 - 使用前需要将它们与iPhone配对

这两种类型是独立管理的 - 从你描述它的方式我希望你的手镯落入&#34;标准&#34;类别,CoreBluetooth只能用于BLE。

要使用已经配对的外部配件,您应该使用ExternalAccessory框架