Search code examples
iosobjective-ccore-bluetooth

CBManager state always unknown


I am trying to check if the bluetooth of a device is on or off. This is the code I've written so far

   CBCentralManager *cbManager = [[CBCentralManager alloc] initWithDelegate:self
                                                                       queue:nil
                                                                     options:
                                   [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
                                                               forKey:CBCentralManagerOptionShowPowerAlertKey]];


    [cbManager scanForPeripheralsWithServices:nil options:
                                    [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
                                                                forKey:CBCentralManagerOptionShowPowerAlertKey]];

    if (cbManager.state==CBCentralManagerStatePoweredOff)
    {
        //do stuff
    }

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    NSString *stateString = nil;
    switch(bluetoothManager.state)
    {
        case CBCentralManagerStateResetting: stateString = @"The connection with the system service was momentarily lost, update imminent."; break;
        case CBCentralManagerStateUnsupported: stateString = @"The platform doesn't support Bluetooth Low Energy."; break;
        case CBCentralManagerStateUnauthorized: stateString = @"The app is not authorized to use Bluetooth Low Energy."; break;
        case CBCentralManagerStatePoweredOff: stateString = @"Bluetooth is currently powered off."; break;
        case CBCentralManagerStatePoweredOn: stateString = @"Bluetooth is currently powered on and available to use."; break;
        default: stateString = @"State unknown, update imminent."; break;
    }
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Bluetooth state"
                                                     message:stateString
                                                    delegate:nil
                                           cancelButtonTitle:@"Okay" otherButtonTitleArray:nil] autorelease];
    [alert show];
}

The problem is that the state of the manager is always Unknown regardless if the bluetooth on the device is turned on or not. Any ideas on why this happens ?


Solution

  • Two things -

    1. Your CBCentralManager should be a property, otherwise it will be released as soon as the method you initialise it in exits

    2. You shouldn't call scanForPeripheralsWithServices until you are in the powered on state.

      @property (strong,nonatomic) CBCentralManager *cbManager;
      
      
      
      self.cbManager = [[CBCentralManager alloc] initWithDelegate:self
                                                                     queue:nil
                                                                   options:
                                 [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
                                                                     forKey:CBCentralManagerOptionShowPowerAlertKey]];
      
      
      - (void)centralManagerDidUpdateState:(CBCentralManager *)central
       {
          NSString *stateString = nil;
          switch(central.state)
          {
              case CBCentralManagerStateResetting: 
                 stateString = @"The connection with the system service was momentarily lost, update imminent."; 
                 break;
              case CBCentralManagerStateUnsupported: 
                 stateString = @"The platform doesn't support Bluetooth Low Energy."; 
                 break;
              case CBCentralManagerStateUnauthorized: 
                 stateString = @"The app is not authorized to use Bluetooth Low Energy."; 
                 break;
              case CBCentralManagerStatePoweredOff: 
                 stateString = @"Bluetooth is currently powered off."; 
                 break;
              case CBCentralManagerStatePoweredOn: 
                 stateString = @"Bluetooth is currently powered on and available to use.";
                 [central scanForPeripheralsWithServices:nil options:
                                  [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
                                                              forKey:CBCentralManagerOptionShowPowerAlertKey]]; 
                 break;
              default: 
                 stateString = @"State unknown, update imminent."; 
                 break;
          }
          UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Bluetooth state"
                                                           message:stateString
                                                          delegate:nil
                                                 cancelButtonTitle:@"Okay" otherButtonTitleArray:nil] autorelease];
          [alert show];
      }