Reputation: 1336
This code allows to determine current bluetooth status:
CBCentralManager* testBluetooth = [[CBCentralManager alloc] initWithDelegate:nil queue: nil];
switch ([testBluetooth state]) {....}
But, when [[CBCentralManager alloc] init...] happens, system popups an alert to user, if bluetooth is off.
Is there any way to check bluetooth status without disturbing my users?
Upvotes: 14
Views: 24301
Reputation: 1540
By combining on BadPirate's and Anas' answer, you can get the bluetooth state without show system alert.
#import <CoreBluetooth/CoreBluetooth.h>
@interface ShopVC () <CBCentralManagerDelegate>
@property (nonatomic, strong) CBCentralManager *bluetoothManager;
@end
@implementation ShopVC
- (void)viewDidLoad {
[super viewDidLoad];
if(!self.bluetoothManager)
{
NSDictionary *options = @{CBCentralManagerOptionShowPowerAlertKey: @NO};
self.bluetoothManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:options];
}
}
#pragma mark - CBCentralManagerDelegate
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
NSString *stateString = nil;
switch(self.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:@"ok" otherButtonTitles: nil];
[alert show];
}
Upvotes: 3
Reputation: 573
In swift you can do write these two lines in your app delegate inside the func: didFinishLaunchingWithOptions launchOptions
self.bCentralManger = CBCentralManager(delegate: self, queue: dispatch_get_main_queue(), options: [CBCentralManagerOptionShowPowerAlertKey: false])
self.bCentralManger.scanForPeripheralsWithServices(nil, options: nil)
where your bCentralManger should be declared as :
private var bCentralManger: CBCentralManager!
Upvotes: 9
Reputation: 178
I've only tested this on iOS 9 so maybe someone could test this one older OS devices.
We do everything normally except one thing, instead of settings the CBCentralManager
Delegate in viewDidLoad
we leave this until the moment we need it, in the example case below I call this once my WKWebView
has finished loading, and because each page of my web view potentially requires the use of Bluetooth I put this in WKWebView didFinishNavigation
.
Swift
var managerBLE: CBCentralManager?
func bluetoothStatus() {
managerBLE = CBCentralManager(delegate: self, queue: nil, options: nil)
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
bluetoothStatus()
}
func centralManagerDidUpdateState(central: CBCentralManager) {
switch managerBLE!.state
{
case CBCentralManagerState.PoweredOff:
print("Powered Off")
case CBCentralManagerState.PoweredOn:
print("Powered On")
case CBCentralManagerState.Unsupported:
print("Unsupported")
case CBCentralManagerState.Resetting:
print("Resetting")
fallthrough
case CBCentralManagerState.Unauthorized:
print("Unauthorized")
case CBCentralManagerState.Unknown:
print("Unknown")
default:
break;
}
}
The moment that delegate is set within bluetoothStatus()
you will see the state change fire.
The notification to turn on Bluetooth only seems to want to be called right at the initial load of your app, doing it this way mean you just get what you want from the centralManagerDidUpdateState
Upvotes: 2
Reputation: 3203
I have used below code to disable alert for iOS 8 and above version
self.bluetoothManager = [[CBCentralManager alloc]
initWithDelegate:self
queue:dispatch_get_main_queue()
options:@{CBCentralManagerOptionShowPowerAlertKey: @(NO)}];
[self.bluetoothManager scanForPeripheralsWithServices:nil options:nil];
Upvotes: 3
Reputation: 4277
I got the following response from an apple developer : In iOS7, the CBCentralManagerOptionShowPowerAlertKey
option lets you disable this alert.
If you havea a CBCentralManager when you initialise it, you can use the method initWithDelegate:queue:options
Example:
In my .h file i have a CBCentralManager * manager
In .m file :
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], CBCentralManagerOptionShowPowerAlertKey, nil];
_manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:options];
[_manager scanForPeripheralsWithServices:nil options:nil];
With this code the warning no longer appears, I hope that helps !
Upvotes: 21
Reputation: 79
There is currently no way to disable this alert when your application is run on a iOS device which supports Bluetooth LE and where Bluetooth is disabled. It would be an enhancement request to provide a means to disable the alert. So the more requests Apple gets about this enhancement, the better.
Upvotes: 1