【问题标题】:How can I get IOBluetoothDevice's battery level, using Swift and AppKit (Xcode for MacOS)如何使用 Swift 和 AppKit (Xcode for MacOS) 获取 IOBluetoothDevice 的电池电量
【发布时间】:2019-04-21 18:06:25
【问题描述】:

我正在使用 Xcode 开发一个 MacOS 应用程序,基于 CocoaAppKit,用 斯威夫特。

我在整个应用程序中使用IOBluetoothDevice 对象,并且我希望能够显示设备的电池电量(如果可以访问)。

我希望电池电量在操作系统的蓝牙设置中可见的设备(见下图)也可以通过编程方式访问(例如,AirPods、妙控键盘等)。但是,我在任何地方都找不到这个。

我也想过执行一个终端命令,发现this thread,但也没成功。

谢谢

【问题讨论】:

标签: swift macos cocoa appkit


【解决方案1】:

您可以使用 IOKit 从 IORegistry 获取蓝牙设备的电池电量。

这是获取 Magic Trackpad 2 电池电量的简单示例

import IOKit

var serialPortIterator = io_iterator_t()
var object : io_object_t
let masterPort: mach_port_t = kIOMasterPortDefault
let matchingDict : CFDictionary = IOServiceMatching("AppleDeviceManagementHIDEventService")
let kernResult = IOServiceGetMatchingServices(masterPort, matchingDict, &serialPortIterator)

if KERN_SUCCESS == kernResult {
    repeat {
        object = IOIteratorNext(serialPortIterator)
        if object != 0, let percent = IORegistryEntryCreateCFProperty(object, "BatteryPercent" as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Int {
            print(percent)
            break
        }
    } while object != 0
    IOObjectRelease(object)
}    
IOObjectRelease(serialPortIterator)

对于其他设备,您必须将AppleDeviceManagementHIDEventServiceTrackpad2 替换为适当的值。您可以使用ioreg -l 在 Terminal.app 中显示整个 IORegistry。

【讨论】:

  • 谢谢!是否在某处列出了所有可能的设备名称列表?或者如何判断我是否连接了两个相同型号的游戏手柄(比如它们支持电池报告),BatteryPercent 与该特定游戏手柄相关?
  • 不,这是大量的调查和反复试验。例如,在 Terminal.app 中使用grepawk 过滤包含 BatteryPercent 的行,并找到树节点和封闭对象的类。为了区分设备,还有其他属性,例如供应商或序列号。
  • 我很惊讶没有更好的 API,因此您可以订阅 batteryPercentChanged 或其他内容。我怀疑蓝牙菜单栏小部件每 5 秒检查一次 for 循环内的 BatteryPercent。
  • 我确信有一个 API 可以观察 IOReg 中的属性。相当低级的 C 回调
  • @meneroush 我的意思是,菜单可能只是在子菜单弹出打开时查询值。为什么需要观察值?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
相关资源
最近更新 更多