我有一个蓝牙手环,可以通过蓝牙连接到我的 iPhone 5s;它附带一个名为 Zeroner 的应用程序。现在我想在不使用App的情况下获取已连接并配对手环的信息。这是我尝试做的事情:
- 设置
CBCentralManager
- 使用
retrieveConnectedPeripheralsWithServices:
获取已连接的设备
这是代码:
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 应用程序取消配对并在“设置”>“蓝牙”中“忘记此设备”> 选择名为“Bracelet-0366”的设备后,LightBlue 应用程序会发现该设备(终于!)。
这是结果截图:
我在这里有几个值,但我不确定应该使用哪些值。
进一步测试结果:
如果我将 LightBlue 中找到的 UUID(以 4EFF 开头)放入 SERVICE_ID
中,则上述代码不会调用任何委托(delegate)。
我尝试过的另一段代码是(从 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_ID
和 TRANSFER_CHARACTERISTIC_ID
。根据教程,TRANSFER_SERVICE_ID
应设置为以 4EFF
开头的值,TRANSFER_CHARACTERISTIC_ID
应设置为 0xFF20
> 或 FF20
。然而,即使手环未配对并断开连接,这段代码也根本不会检测到手环。这次我错过了什么?
最佳答案
不必担心以 4EFF
开头的 UUID - 这是设备的 UUID,每个设备都不同。
服务 ID 为 FF20
- 您可以在 scanForPeripheralsWithServices
中使用它 - 这是上面代码中的 SERVICE_ID
。
那么你有两个特征 - FF21
和 FF22
您可以使用 CBPeripheral
实例上的 writeValue
方法写入 FF21
。
使用 FF22
,您可以使用 setNotify
CBPeripheral
方法订阅通知。然后,每当设备更改值时,您都会调用 didUpdateValueForCharacteristic
CBPeripheralDelegate
方法。
关于ios - 核心蓝牙框架 : How to obtain connected devices without knowing the Service IDs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30450767/