43

我试图以编程方式获取 iPhone/iPod 蓝牙的状态,无论它是打开还是关闭。是否可以使用一些 Apple API 或第三方 API。

4

7 回答 7

50

对Sam 的回答进行一些研究,我想我会分享您可以在不使用私有 API 的情况下这样做,但有一些注意事项:

  • 它仅适用于 iOS 5.0+
  • 它仅适用于支持蓝牙 LE 规格的设备(iPhone 4S+、第 5 代 iPod+、iPad 第 3 代+)
  • 简单地分配类将导致您的应用程序向用户询问使用蓝牙堆栈的权限(可能不需要),如果他们拒绝,您将看到的唯一内容是 CBCentralManagerStateUnauthorized iOS7+ 修订:上述删除线现在可以是阻止,请参阅下面指向此答案的评论,这说明您可以将 CoreBluetooth 的CBCentralManagerOptionShowPowerAlertKey选项设置为 NO 以阻止权限提示。
  • 蓝牙状态的检索是异步且连续的。您需要设置一个委托来获取状态更改,因为检查新分配的蓝牙管理器的状态将返回 CBCentralManagerStateUnknown

话虽如此,这种方法似乎确实提供了蓝牙堆栈状态的实时更新。

包含CoreBluetooth框架后,

#import <CoreBluetooth/CoreBluetooth.h>

这些测试很容易使用:

- (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];
}
于 2013-03-21T21:10:48.213 回答
25

要禁用默认警报消息,您只需要在实例化 CBPeripheralManager 时传递一个选项字典:

SWIFT 在 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)

显然,您还需要实现如上所述的 CKManagerDelegate 委托方法 peripheralManagerDidUpdateState:

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
    }
}
于 2015-07-16T08:52:44.573 回答
12

这个答案已经从最初的 Objective-C 更新到 Swift 4.0。

假设您已经创建了一个蓝牙管理器并将委托分配给ViewController该类。

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")
        }
    }
}
于 2015-02-16T20:26:42.497 回答
6

BadPirate 回答的一些更新,在 iOS7 中,您可以设置中央管理器在分配管理器对象时不显示警报,方法是给它一个 NSDictionary,其键“CBCentralManagerOptionShowPowerAlertKey”设置为 0。

self.cbManager = [[CBCentralManager alloc] initWithDelegate:self
                                                          queue:nil
                                                        options:
                      [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
                                                  forKey:CBCentralManagerOptionShowPowerAlertKey]];
于 2014-09-08T04:32:39.947 回答
2

在 iOS 5 及更高版本上有一种使用 CoreBluetooth 的方法。您可以使用的类是 CBCentralManager。它有一个属性“状态”,您可以检查蓝牙是否打开。(枚举 CBCentralManagerState 具有您要检查的值)。

于 2012-08-02T15:28:51.703 回答
1

完成设置后,CBCentralManager您可以使用委托方法或直接使用。CBCentralManager::stateCBCentralManager::authorization

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
        }
    }
}
于 2019-11-21T08:21:23.083 回答
0

这个解决方案有点老了,在苹果推出核心蓝牙之前

- (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 

    }
于 2011-07-07T06:37:45.027 回答