# 让 MacBook 在合上盖子后确实关闭蓝牙

> 本文开放前 70% 正文，剩余内容会员可见。

原文：https://utgd.net/article/21417

在所有的笔记本电脑生产商中，Apple 是唯一一家从未想明白过盖子为何物的公司：盖上盖子，究竟意味着什么？

一方面，异于其他平台，MacBook 上的绝大多数进程旋即中止，在不破坏系统完整性的前提下，你甚至不能继续听歌，更别说跑本地 AI Agent；另一方面，依然有许多进程在偷偷运行，尤其是根本不能用的蓝牙耳机，依然反复连接、断开、连接、断开、连接、断开……

（当你把电脑放在隔壁房间时，蓝牙信号若隐若现，双耳将被反复断开和连接的提示音覆盖，耳机彻底无法使用，而且耳机也无权主动断开，最终你再也受不了，起身走出房间关死蓝牙。）

有人戏称，已经盖上盖子的 MacBook，还喜欢和手机等正在使用的设备“抢蓝牙”。Apple 的狂热爱好者可能会说，最新发布的、最新固件的、最新批次的、最昂贵的、配备无线充电盒的……（请继续追加条件）……AirPods \(Pro\) 没有这个问题，真可怜，这些家伙只是还没有遇到——或选择性无视——随机播放音乐的祖传 bug。遇到时，他们轻则享受不便，重则创造一个新的社死传说。

我不关心 MacBook 的设计团队有什么良苦用心，也无所谓异国情报部门会如何利用无法关闭的蓝牙大门（这都不算后门了），我只在乎一件事：怎么彻底关死它？

如何在盒盖时彻底关闭蓝牙？这个问题至少困扰了 MacBook 用户十几年，甚至催生了好几个开源项目。这类软件，显然要惹用心良苦的设计师不开心（或者让可能存在的情报机构不高兴），技术上也是独辟蹊径，均属搭载火山口上，随时可能失效——事实上，好几个已经失效了。

既然反正是临时私搭乱建，何不自己动手？万一失效，也知道如何修补。我随机意识到，Keyboard Maestro 是理想的违建工具，只需逐个击破以下各环节：

- 合上盖子，触发动作；

- 打开盖子，触发动作；

- 打开蓝牙和关掉蓝牙。

真正撸起袖子之后，才会发现，任何一步都没有现成答案。Keyboard Maestro 并不能直接识别盖子何时盖上，反之亦然，不过，这恰恰是重新审视操作流程的好机会：没有直接的触发机关，就看看同步会发生什么，进而尝试共轭控制。

除非接上外置显示器，通常在合上盖子时，电脑也进入休眠模式。那么，顺理成章，System Sleep 条件可以触发合盖后的自动操作。

至于开盖，Keyboard Maestro 论坛有过一场激烈讨论，答案同样是找关联线索：开盖后几乎必然马上要解锁电脑，那么，解锁就足以代表开盖。

涉及外置显示器时，盖子开合状况更复杂，而且此时往往需要外置的键盘和鼠标，蓝牙不能一概关死，有需要的读者可查看 Keyboard Maestro 论坛上的另一串讨论。

设置触发条件后，就要想办法打开和关闭蓝牙。借助 GUI Scripting 显然不妥——不管你多想让 Agent 这么干！——因为盖子盖上后只有瞬间，根本没有时间慢吞吞地模拟键鼠操作。前文提及的第三方软件，大多也是八仙过海，像闯空门一样四处寻找暂未被 macOS 堵死的 API。本文也不例外，我使用了一个官方的蓝牙接口，关闭蓝牙的Swift 代码如下：

```
import Foundation
import IOBluetooth
@_silgen_name("IOBluetoothPreferenceSetControllerPowerState")
func setBluetoothPower(_ state: Int32)
@_silgen_name("IOBluetoothPreferenceGetControllerPowerState")
func getBluetoothPower() -> Int32
setBluetoothPower(0)
Thread.sleep(forTimeInterval: 2)
if get
```

---

[前往标准阅读页](https://utgd.net/article/21417?audience=web)
