How to get the status of bluetooth (ON/OFF) in iphone programmatically
Asked Answered
F

7

43

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.

Flick answered 10/2, 2011 at 8:53 Comment(0)
R
49

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:

  • It will only work on iOS 5.0+
  • It will only work on devices that support the bluetooth LE spec (iPhone 4S+, 5th Generation iPod+, iPad 3rd Generation+)
  • Simply allocating the class will cause your application to ask permission to use the bluetooth stack from the user (may not be desired), and if they refuse, the only thing you'll see is CBCentralManagerStateUnauthorized iOS7+ Revision: Aforementioned strike-through can now be prevented, see comments below which point to this answer which explains you can set CoreBluetooth's CBCentralManagerOptionShowPowerAlertKey option to NO to prevent permissions prompt.
  • Retrieval of bluetooth state is async, and continuous. You will need to setup a delegate to get state changes, as checking the state of a freshly allocated bluetooth manager will return CBCentralManagerStateUnknown

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];
}
Romeyn answered 21/3, 2013 at 21:10 Comment(6)
You mentioned that implicitly, but for consistency: declare property @property (nonatomic, strong) CBCentralManager* bluetoothManager; and set your class conforms to protocol CBCentralManagerDelegateAvatar
This hasn't worked for me. Has someone gotten this to work for them? iOS7+Threlkeld
You can avoid the alert message using the designated initializer on CBCentralManager, check out this answer: https://mcmap.net/q/261071/-ios-corebluetooth-passively-check-if-bluetooth-is-enabled-without-prompting-user-to-turn-bluetooth-onDeparted
is this method accepted by apple? Or they will reject the app using it?Latashalatashia
@Signo - No issues with Apple, though some reports that it's not working anymore.Romeyn
@Romeyn It indeed still works now. People are likely reading the state immediately (which will always return (int)0), rather than waiting for the delegate callback.Mandamus
R
25

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
    }
}
Roden answered 16/7, 2015 at 8:52 Comment(4)
how to add property CBPeripheralManager in swift.It says cannot find an initializer for type "CBPeripheralManager"Coition
@Aravind.A add import CoreBluetooth to the top of your source fileDesinence
This piece of code is great for silent check for bluetooth status (on/off, etc.)Advisement
Does this work in the background, or only when the app is on-screen?Judo
L
13

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")
        }
    }
}
Localism answered 16/2, 2015 at 20:26 Comment(0)
J
6

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]];
Jenicejeniece answered 8/9, 2014 at 4:32 Comment(0)
S
2

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).

Standoffish answered 2/8, 2012 at 15:28 Comment(1)
This will only work for devices with BT LE, i.e. iPhone 4S+, iPad 3+Sewel
S
1

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
        }
    }
}
Schaffner answered 21/11, 2019 at 8:21 Comment(0)
W
0

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 

    }
Wrongheaded answered 7/7, 2011 at 6:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.