Reputation: 85
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 ?
Upvotes: 1
Views: 4789
Reputation: 2825
I had the same issue after upgrade from Sierra, Xcode 8, Swift 3 to High Sierra, Xcode 9, Swift 4.
Solution 1: (Just for tests) Wait a second bit between init and start of scan
var scanner = BLESensorScanner(sensorName: sensorName);
sleep(1);
DispatchQueue.global(qos: .userInteractive).async {
if (scanner.isPoweredOn()) {
DBG("Bluetooth is powered on");
scanner.startScan();
}
else {
DBG("Bluetooth is not powered");
exit(-1);
}
}
Note: BLESensorScanner
implements NSObject
, CBCentralManagerDelegate
, CBPeripheralDelegate
. sensorName
is the name of the bluetooth device
Solution 2: Use event handler to wait until state becomes poweredOn
public func centralManagerDidUpdateState(_ central: CBCentralManager) {
DBG("CBCentralManager.centralManagerDidUpdateState");
DBGI("state=\(toString(central.state))");
if (state == CBManagerState.poweredOn) {
scanner.startScan();
}
}
Upvotes: -1
Reputation: 114773
Two things -
Your CBCentralManager
should be a property, otherwise it will be released as soon as the method you initialise it in exits
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];
}
Upvotes: 3
Reputation: 38
the method
-(void)centralManagerDidUpdateState(CBCentralManager*)central
is called. try to implement this one
- (void)centralManagerDidUpdateState:(CBCentralManager *)central { // Possible states that the central manager can return. char *managerStrings[] = {"Unknown Error", "Resetting", "Unsupported Device", "Unauthorized", "Bluetooth is deactivated", "PoweredOn"}; NSString *managerString = [NSString stringWithFormat:@"%s", managerStrings[central.state]]; // the search is enabled if everything is ok if ([managerString isEqualToString:@"PoweredOn"]) { //Do something } }
Upvotes: -1