Bluetooth 4.0 完整使用

1、首先先对蓝牙状态的一种识别,使用ENUM进行状态判别,分别使用<span style="font-family: Arial, Helvetica, sans-serif;">BluetoothState表示蓝牙连接状态和</span><span style="font-family: Arial, Helvetica, sans-serif;">BluetoothFailState表示蓝牙连接失败的状态,对BluetoothState和BluetoothFailState设置成全局变量,如下方所示</span>
</pre><pre name="code" class="objc">typedef NS_ENUM(NSInteger, BluetoothState){
    BluetoothStateDisconnect = 0,
    BluetoothStateScanSuccess,
    BluetoothStateScaning,
    BluetoothStateConnected,
    BluetoothStateConnecting
};

typedef NS_ENUM(NSInteger, BluetoothFailState){
    BluetoothFailStateUnExit = 0,
    BluetoothFailStateUnKnow,
    BluetoothFailStateByHW,
    BluetoothFailStateByOff,
    BluetoothFailStateUnauthorized,
    BluetoothFailStateByTimeout
};

</pre><p>2、在连接界面,如<span style="font-family:Menlo; font-size:18px">IsConnectBleViewController,在.h文件中定义</span></p><p><span style="font-family:Menlo; font-size:18px"></span></p><p style="margin-top:0px; margin-bottom:0px; font-size:18px; line-height:normal; font-family:Menlo"></p><pre name="code" class="objc">@property (strong, nonatomic) CBCentralManager * centralManager;
@property (strong, nonatomic) CBPeripheral * discoveredPeripheral;
@property (strong, nonatomic) CBCharacteristic * writeCharachter;


IsConnectBleViewController.m文件中

//蓝牙状态  -- self.seachRssultLabel为文本提示

- (void)bleState
{
    if (bluetoothFailState == BluetoothFailStateUnExit) {
        switch (bluetoothState) {
            case BluetoothStateConnected:
                self.searchResultLabel.text =[NSString stringWithFormat:@"%@",NSLocalizedString(@"已连接", nil)];
                
                break;
            case BluetoothStateConnecting:
                self.searchResultLabel.text = NSLocalizedString(@"连接中......", nil);
                
                break;
            case BluetoothStateDisconnect:
                self.searchResultLabel.text = NSLocalizedString(@"蓝牙已断开", nil);
                
                break;
            case BluetoothStateScanSuccess:
                self.searchResultLabel.text = NSLocalizedString(@"搜索成功,请选择你需要连接的蓝牙设备", nil);
                break;
            case BluetoothStateScaning:
                self.searchResultLabel.text = NSLocalizedString(@"搜索中", nil);
                break;
            default:
                break;
        }
    }else {
        switch (bluetoothFailState) {
            case BluetoothFailStateByHW:
                self.searchResultLabel.text = NSLocalizedString(@"蓝牙硬件不支持", nil);
                break;
            case BluetoothFailStateByOff:
                self.searchResultLabel.text = NSLocalizedString(@"蓝牙关闭了", nil);
                break;
            case BluetoothFailStateByTimeout:
                self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接超时", nil);
                break;
            case BluetoothFailStateUnauthorized:
                self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接失败", nil);
                break;
            case BluetoothFailStateUnKnow:
                self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接错误", nil);
                break;
            case BluetoothFailStateUnExit:
                self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接中...", nil);
                break;
            default:
                break;
        }
    }
    
}


--------  搜索蓝牙的办法 -----

[self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @NO}];//搜索所有的蓝牙服务
 self.centralManager.delegate = self;//必须遵循代理
 bluetoothState = BluetoothStateScaning;//蓝牙状态变为搜索状态
[self bleState];
[self performSelector:@selector(searchBluetoothJumpTimeOut) withObject:nil afterDelay:10];//10表示搜索时间,10秒没有搜索到即定义为连接超时
#pragma mark - 蓝牙连接超时的方法
- (void)searchBluetoothJumpTimeOut
{
    
    if (bluetoothState == BluetoothStateScaning) {
        bluetoothFailState = BluetoothFailStateByTimeout;
        [self ScanBle];//超时之后 -- 的操作,如果不需要超时后继续连接,则不需要这部步
        self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接超时,请重新搜索", nil);

    }
}

#pragma mark - 搜索蓝牙
-(void)ScanBle{
    
    if(bluetoothFailState == BluetoothFailStateByTimeout){//连接超时
        [self.centralManager scanForPeripheralsWithServices:nil
                                                    options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @NO }];
        self.searchResultLabel.text = NSLocalizedString(@"正在搜索您的设备,请稍等...", nil);
        
        bluetoothState = BluetoothStateScaning;//蓝牙状态变化成可搜索状态
        
        [self bleState];//蓝牙的状态
        
        [self performSelector:@selector(searchBluetoothJumpTimeOut) withObject:nil afterDelay:10];//如果连接超时
        
    }
    
    if(bluetoothFailState==BluetoothFailStateByOff){
        self.promptLab.text= NSLocalizedString(@"检查您的蓝牙是否开启后重试", nil);//如果蓝牙设备关闭,提示打开蓝牙设备 -- 弹出视图提示
        [self showPromptLab];
    }
     
}

#pragma mark CBCentralManagerDelegate --- 中心设备(手机)的代理方法,即上面定义的 self.centralManager.delegate = self;//必须遵循代理

监控手机的蓝牙状态,一旦蓝牙被关闭可提醒

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    if (central.state != CBCentralManagerStatePoweredOn) {//end to do
        // In a real app, you'd deal with all the states correctly
        
        NSLog(@"fail, state is off.");
        
        switch (central.state) {
            case CBCentralManagerStatePoweredOff:

                self.searchResultLabel.text = NSLocalizedString(@"连接失败了,请您再检查一下您的手机蓝牙是否开启,然后再试一次吧", nil);
                bluetoothFailState = BluetoothFailStateByOff;
                break;

            case CBCentralManagerStateResetting:
                bluetoothFailState=BluetoothFailStateByTimeout;
                break;

            case CBCentralManagerStateUnsupported:
                self.searchResultLabel.text = NSLocalizedString(@"检测到您的手机不支持蓝牙4.0,所以建立不了连接.建议更换您的手机再试试。", nil);
                bluetoothFailState = BluetoothFailStateByHW;
                break;

            case CBCentralManagerStateUnauthorized:
                self.searchResultLabel.text = NSLocalizedString(@"连接失败了,请您再检查一下您的手机蓝牙是否开启,然后再试一次吧", nil);
                bluetoothFailState = BluetoothFailStateUnauthorized;
                break;

            case CBCentralManagerStateUnknown:
                bluetoothFailState = BluetoothFailStateUnKnow;
                self.searchResultLabel.text = @"";
                break;
                
            default:
                break;
        }
        
        return;
    }
    
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙已经开启!点击开始搜索连接你的设备", nil);
    bluetoothFailState = BluetoothFailStateUnExit;
    
}



/*

 中心设备扫描外围设备

 */

-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{
    
    
    if (peripheral == nil||peripheral.identifier == nil/*||peripheral.name == nil*/) {
        return;
    }

    /*
            蓝牙列表去重,防止重复的出现 --- 将 外围设备添加到数组中,主要针对多选,一对一可设置self.isConnectMuArra变成一个全局的peripheral
     */
    NSMutableArray * repetitionMuArray = [[NSMutableArray alloc]init];
    
    [repetitionMuArray addObject:peripheral];
    
    for (unsigned i = 0; i < repetitionMuArray.count; i++) {
        
        if ([self.isConnectMuArray containsObject:[repetitionMuArray objectAtIndex:i]] == NO) {
            [self.isConnectMuArray addObject:[repetitionMuArray objectAtIndex:i]];
        }
    }
    
    //搜索成功后,修改蓝牙状态
    bluetoothFailState = BluetoothFailStateUnExit;
    bluetoothState = BluetoothStateScanSuccess;//蓝牙状态为搜索成功
    
    [self bleState];//中心设备状态实时监控
    
    //输出广播名
    NSString *CBName1=[advertisementData valueForKeyPath:CBAdvertisementDataLocalNameKey];
    NSLog(@"广播名1:%@",CBName1);
    
}


3、扫描设备成功后进行连接


for (int i = 0; i < self.isConnectMuArray.count ; i++) {
            CBPeripheral * selectPeripheral = self.isConnectMuArray[i];
                    [self.centralManager connectPeripheral:selectPeripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@YES}];
      }


连接之后执行连接的代理方法

#pragma mark - 已经连接蓝牙设备
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{

    [self.centralManager stopScan];//连接成功后停止搜索
    
    bluetoothState=BluetoothStateConnected;
    [self bleState];
    //discoveredPeripheral是全部变量 多连接是否需要创建数组?
    discoveredPeripheral=peripheral;  /----   前面所说如果是需要一对一创建全局变量 -----  如果一对多,则选择下面一步添加数组/
    discoveredPeripheral.delegate = self;
    [(sysDege).discoverPeripheralArray addObject:peripheral];//(sysDege).discoverPeripheralArray是全局数组    

     [peripheral discoverServices:@[[CBUUID UUIDWithString:UUID_SERVICE]]];//设置扫描 -- 外围设备扫描自己的服务   UUID_SERVICE是硬件方面的序列号,可为nil

    [[NSNotificationCenter defaultCenter]postNotificationName:@"ConnectSuccess" object:nil];//通知成功的消息
    
}

上一步连接成功外围设备,就开始发送扫描服务的指令,在这里执行扫描到服务的代理办法

#pragma mark - 外围设备已经被发现
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    if (error) {//如果发现错误
        NSLog(@"Error discovering services: %@", [error localizedDescription]);
        return;
    }

    NSLog(@"外围设备已被发现peripheral.services%@",peripheral.services);
    
    for (CBService * service in peripheral.services) {
        
        [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:UUID_CHARACTERISTIC]] forService:service];//扫描到服务就可以发送扫描特性的指令
        
        return;
    }
    
}

#pragma mark - 外围设备扫描到特性

-(void)peripheral:(CBPeripheral *)aPeripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    
    for (CBCharacteristic * achar in service.characteristics) {
        
        NSLog(@"外围设备Discovered characteristic:CBCharacteristic * achar%@", achar);
        
        NSLog(@"service uuid:%@ characteristics UUID:%@,achar.value:%@",service.UUID,achar.UUID,achar.value);
        
#pragma mark - 扫描到特性后 设置读写
        [aPeripheral readValueForCharacteristic:achar];
        [aPeripheral setNotifyValue:YES forCharacteristic:achar];//修改通知的状态
 
        //可读写的特性?
        if (self.writeCharachter != achar) {
            self.writeCharachter = achar;
            writeCharachter = achar;

        
        if (self.discoveredPeripheral != aPeripheral) {
            self.discoveredPeripheral = aPeripheral;
        }
	//可以通过不同的UUID进行发送不同的指令
	[self writeCommand:data];
    }
}

#pragma mark - 写入特性

-(void)writeCommand:(NSData *)data{
    
    NSLog(@"writeCommand:(NSData *)data:%@",data);
    //    连接外围设备为空或者蓝牙状态为断开,退出
    if (self.discoveredPeripheral == nil||bluetoothState == BluetoothStateDisconnect) {
        return;
    }
    
    
    [self.discoveredPeripheral writeValue:data
                        forCharacteristic:self.writeCharachter
                                     type:CBCharacteristicWriteWithResponse];
    NSLog(@"write command is success");
     
}


//发送指令后可以得到硬件返回的信息


#pragma mark - 特性值变化

- (void) peripheral:(CBPeripheral *)aPeripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
              error:(NSError *)error
{
    
    
    NSLog(@"特性回调值:%@",characteristic);
    
    NSString *result = [[NSString alloc] initWithData:characteristic.value  encoding:NSUTF8StringEncoding];
    NSLog(@"特性回调值的温度:%@",result);
  
}



连接不成功 -- 即断开

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{

    self.discoveredPeripheral = nil;//断开之后为空  -- 一对一的方法,一对多为(sysDege).discoverPeripheralArray数组清空
    bluetoothState = BluetoothStateDisconnect;
    [self bleState];
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙设备已经断开了,请重新搜索", nil);

    [[NSNotificationCenter defaultCenter]postNotificationName:@"bleDis" object:nil];//发送蓝牙断开的通知 

}

蓝牙发送数据 --  self.discoveredPeripheral表示外围设备 -- self.writeCharachter表示特性  
[self.discoveredPeripheral writeValue:data
                        forCharacteristic:self.writeCharachter
                                     type:CBCharacteristicWriteWithResponse];




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值