如何以编程方式获取 iPhone 中蓝牙的状态(开/关)

发布于 2024-10-16 12:09:12 字数 76 浏览 5 评论 0原文

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

潦草背影 2024-10-23 12:09:12

Sam 的回答进行了一些研究,我想我会分享
您可以在不使用私有 API 的情况下执行此操作,但有一些注意事项:

  • 它仅适用于 iOS 5.0+
  • 它仅适用于以下设备:
    支持蓝牙 LE 规范(iPhone 4S+、第 5 代 iPod+、iPad
    第三代+)
  • 简单地分配该类将导致您的应用程序向用户请求使用蓝牙堆栈的权限(可能不需要),如果他们拒绝,您将看到的唯一内容是 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];
}

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];
}
笑叹一世浮沉 2024-10-23 12:09:12

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

在 iOS8+ 上测试的 SWIFT

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

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
    }
}
雄赳赳气昂昂 2024-10-23 12:09: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")
        }
    }
}

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")
        }
    }
}
坏尐絯 2024-10-23 12:09:12

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

self.cbManager = [[CBCentralManager alloc] initWithDelegate:self
                                                          queue:nil
                                                        options:
                      [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
                                                  forKey:CBCentralManagerOptionShowPowerAlertKey]];

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]];
绝不服输 2024-10-23 12:09:12

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

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

孤者何惧 2024-10-23 12:09:12

一旦您完成了 CBCentralManager 设置,您就可以从 委托方法或直接委托方法。

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

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
        }
    }
}
萌化 2024-10-23 12:09:12

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

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

    }

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 

    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文