iOS进阶

iOS BLE(蓝牙4.0) 读取埃微i5智能手环步数的简单实现

2016-03-28  本文已影响840人  佘红响
/**
 *  懒加载 初始化中心设备 CBCentralManager
 *
 *  @return 中心设备
 */
- (CBCentralManager *)centralManager {
    if (!_centralManager) {
        _centralManager = [[CBCentralManager alloc]initWithDelegate:self queue:nil options:nil];
    }
    return _centralManager;
}
- (void)scanPeripheral {
    // 2.扫描外设
    if(self.centralManager.state == CBCentralManagerStatePoweredOff) {           // 蓝牙关闭状态
        
        [[[UIAlertView alloc] initWithTitle:@"蓝牙是关闭状态"
                                    message:@"请打开蓝牙"
                                   delegate:self
                          cancelButtonTitle:@"dismiss"
                          otherButtonTitles: nil] show];
        
    } else if(self.centralManager.state == CBCentralManagerStateUnsupported) {   // 设备蓝牙不支持
        
        [[[UIAlertView alloc] initWithTitle:@"设备蓝牙不支持"
                                    message:@"必须 iPhone4S 以上的设备才支持蓝牙4.0"
                                   delegate:self
                          cancelButtonTitle:@"dismiss"
                          otherButtonTitles: nil] show];
        
    } else if(self.centralManager.state == CBCentralManagerStatePoweredOn) {    // 蓝牙打开状态
        if (self.peripherals.count) {
            // 连接外设
            [self.centralManager connectPeripheral:[self.peripherals firstObject] options:nil];
            return;
        }
        NSLog(@"蓝牙已经打开, 正在搜索中...");
        self.connectStateLabel.text = @"正在搜索外设中...";
        // 如果第一个参数为nil, 那么将会扫描所有可用的外围设备, 不过这样会很慢
        [self.centralManager scanForPeripheralsWithServices:nil
                                                    options:nil];
    }
}
/**
 *  如果蓝牙状态改变, 会在这个方法回调
 *
 *  @param central 中心设备(一般为你的iPhone)
 */
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {

    [self scanPeripheral];
}
/**
 *  这个代理方法中可以获取外设的信息
 *  4. 可以这里连接外设
 *  @param central           中心设备
 *  @param peripheral        外设
 *  @param advertisementData
 *  @param RSSI
 */
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    
    NSLog(@"已经搜索到设备, 正在连接中...");
    
    self.connectStateLabel.text = @"正在连接设备...";
    
    // 这里可以停止扫描外围设备
    [self.centralManager stopScan];
    
    if (![self.peripherals containsObject:peripheral]) {
        
        NSLog(@"外设名称: %@", peripheral.name);
        
        // 显示设备名称
        [self setUpName:peripheral.name];
        
        peripheral.delegate = self;
        
        // 应该保留外设, 否则会被释放
        [self.peripherals addObject:peripheral];

    }
    
    // 连接外设
    [self.centralManager connectPeripheral:peripheral options:nil];
    
}
/**
 *  如果连接成功的话会回调这个方法
 *  5. 扫描外设中的服务
 *  @param central 中心设备
 *  @param peripheral 外设
 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    
    self.connectStateLabel.text = @"连接成功, 同步数据中...";
    
    // 查找服务
    [peripheral discoverServices:nil];
    
}
/**
 *  连接失败
 *
 */
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    
    self.connectStateLabel.text = @"连接失败...";
    
    self.deviceNameKeyLabel.hidden = YES;
    self.deviceNameValueLabel.hidden = YES;
    
    [self scanPeripheral];
}
/**
 *  7. 从外设的services属性中获取服务列表
 *
 *  @param peripheral 外设
 *  @param error      错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    
    NSLog(@"已经获取到服务列表, 正在匹配服务中...");
    
    if (error) {
        NSLog(@"Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]);
        
//        if ([self.delegate respondsToSelector:@selector(DidNotifyFailConnectService:withPeripheral:error:)])
//            [self.delegate DidNotifyFailConnectService:nil withPeripheral:nil error:nil];
        return;
    }
    
    // 遍历服务
    for (CBService *service in peripheral.services) {
        NSLog(@"%@", service.UUID);
        
//        [peripheral discoverCharacteristics:nil forService:service];
        // 找到对应的服务
        if ([service.UUID isEqual:[CBUUID UUIDWithString:@"FF20"]]) {
//            NSLog(@"Service found with UUID: %@", service.UUID);
            // 查找特征
            [peripheral discoverCharacteristics:nil forService:service];
            break;
        }

    }
    
}
/**
 *  返回已经发现的特性的代理方法
 *  8. 发现服务中的特征
 *  @param peripheral 外设
 *  @param service    服务
 *  @param error      错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    
    if (error) {
        NSLog(@"Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);
        return;
    }
    
//    NSLog(@"\n服务: %@", service.UUID);
    // 从服务中遍历特征
    for (CBCharacteristic *characteristic in service.characteristics) {
//        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"FF22"]]) {
            // 这里要注意有些特征可读, 有些特征可写, 有些可以发通知, 而不是随便调用读写或者发通知的方法的
            // [peripheral readValueForCharacteristic:characteristic];
            // [peripheral discoverDescriptorsForCharacteristic:characteristic];
            // 发送通知
            [peripheral setNotifyValue:YES forCharacteristic:characteristic];
        }

    }
}
/**
 *  9.与外设进行数据交互
 *
 *  @param peripheral     外设
 *  @param characteristic 特征
 *  @param error          错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    
    if (error) {
        NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
        return;
    }
    
    NSData *data = characteristic.value;
    char scartchVal[data.length];
    int16_t dataTemp;
    [data getBytes:&scartchVal length:data.length];
    
    long len = sizeof(scartchVal) / sizeof(scartchVal[0]);
    
    // 可能返回的字节数小于20, 那些情况没有分析, 所以暂且过滤掉
    if ((sizeof(scartchVal) / sizeof(scartchVal[0])) == 20) {
        // 对于埃微智能手环, 如果返回20个字节的话, 那么第8, 9位存储步数
        dataTemp = ((scartchVal[8] & 0xff) + ((scartchVal[9] << 8) & 0xff00));
        self.connectStateLabel.text = @"数据同步成功";
        self.stepLabel.text = [NSString stringWithFormat:@"%d", dataTemp];
    }
    ```

- 最后这里附上一篇不错的BLE的文章http://www.jianshu.com/p/84b5b834b942 (http://www.jianshu.com/p/84b5b834b942)
上一篇下一篇

猜你喜欢

热点阅读