Reputation: 431
I trying to get the Status of iPhone/iPod Bluetooth that whether it is ON or OFF programmatically. Is it possible using some Apple API or third party API.
Upvotes: 43
Views: 59112
Reputation: 5854
Once you have the CBCentralManager
setup you can use CBCentralManager::state
and CBCentralManager::authorization
either from a delegate method or directly.
import CoreBluetooth
class Manager {
let centralManager = CBCentralManager(delegate: self, queue: nil)
var isBTTurnedOn: Bool {
return centralManager.state == .poweredOn
}
var isAuthorized: Bool {
if #available(iOS 13.0, *) {
return centralManager.authorization == .allowedAlways
} else {
return true
}
}
}
Upvotes: 1
Reputation: 26177
A little bit of research into Sam's answer that I thought I'd share You can do so without utilizing private API, but with a few caveats:
CBCentralManagerOptionShowPowerAlertKey
option to NO to prevent permissions prompt. That being said, this method does seem to provide real time updates of bluetooth stack state.
After including the CoreBluetooth framework,
#import <CoreBluetooth/CoreBluetooth.h>
These tests were easy to perform using:
- (void)detectBluetooth
{
if(!self.bluetoothManager)
{
// Put on main queue so we can call UIAlertView from delegate callbacks.
self.bluetoothManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
}
[self centralManagerDidUpdateState:self.bluetoothManager]; // Show initial state
}
- (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: 49
Reputation: 471
To disable the default alert message you just need to pass through an option dictionary when you instantiate the CBPeripheralManager:
SWIFT tested on iOS8+
import CoreBluetooth
//Define class variable in your VC/AppDelegate
var bluetoothPeripheralManager: CBPeripheralManager?
//On viewDidLoad/didFinishLaunchingWithOptions
let options = [CBCentralManagerOptionShowPowerAlertKey:0] //<-this is the magic bit!
bluetoothPeripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: options)
Obviously you also need to implement the CKManagerDelegate delegate method peripheralManagerDidUpdateState as outlined above as well:
func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager!) {
var statusMessage = ""
switch peripheral.state {
case .poweredOn:
statusMessage = "Bluetooth Status: Turned On"
case .poweredOff:
statusMessage = "Bluetooth Status: Turned Off"
case .resetting:
statusMessage = "Bluetooth Status: Resetting"
case .unauthorized:
statusMessage = "Bluetooth Status: Not Authorized"
case .unsupported:
statusMessage = "Bluetooth Status: Not Supported"
case .unknown:
statusMessage = "Bluetooth Status: Unknown"
}
print(statusMessage)
if peripheral.state == .poweredOff {
//TODO: Update this property in an App Manager class
}
}
Upvotes: 25
Reputation: 36612
This answer has been updated from the original Objective-C to Swift 4.0.
It is assumed that you have already created a bluetooth manager and assigned the delegate to the ViewController
class.
import CoreBluetooth
extension ViewController : CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
print("powered on")
case .poweredOff:
print("powered off")
case .resetting:
print("resetting")
case .unauthorized:
print("unauthorized")
case .unsupported:
print("unsupported")
case .unknown:
print("unknown")
}
}
}
Upvotes: 13
Reputation: 6015
This solution is bit old , before apple introducing core bluetooth
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
Class BluetoothManager = objc_getClass( "BluetoothManager" ) ;
id btCont = [BluetoothManager sharedInstance] ;
[self performSelector:@selector(status:) withObject:btCont afterDelay:1.0f] ;
return YES ;
}
- (void)status:(id)btCont
{
BOOL currentState = [btCont enabled] ;
//check the value of currentState
}
Upvotes: 0
Reputation: 101
Some updates on BadPirate's answer, with iOS7 you can set the central manager not to show the alert when allocating the manager object by giving it a NSDictionary that has key "CBCentralManagerOptionShowPowerAlertKey" set to 0.
self.cbManager = [[CBCentralManager alloc] initWithDelegate:self
queue:nil
options:
[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
forKey:CBCentralManagerOptionShowPowerAlertKey]];
Upvotes: 6
Reputation: 19
There is a way on iOS 5 and above using CoreBluetooth. The class you can use is CBCentralManager. It has a property 'state' that you can check to see if Bluetooth is on or not. (the enum CBCentralManagerState has the value(s) you want to check against).
Upvotes: 2