如何通过Python经蓝牙连接iOS设备获取系统通知(RPI场景)
你之前查阅资料时提到的「ASCN」为拼写错误,实际是Apple Notification Center Service (ANCS),这是苹果官方面向第三方BLE外设开放的系统级通知同步服务,也是无需在iOS端安装自研App、直接获取系统全量通知的唯一低门槛可行路径,不需要苹果MFi认证,完全可以基于Python+BlueZ栈实现。
智能手表、车机等设备获取iOS通知,绝大多数走的就是ANCS(低功耗蓝牙设备)或经典蓝牙MAP Profile(传统车载蓝牙设备),你之前用pybluez、bleak直接裸连搜不到相关服务,核心原因是iOS仅对完成配对、且被识别为合规通知类外设的设备开放ANCS服务,通用设备身份连接时iOS不会暴露该服务。
前置蓝牙配置
- 修改蓝牙适配器设备类型,让iOS将其识别为支持通知同步的外设:
编辑BlueZ配置文件/etc/bluetooth/main.conf,找到Class配置项,修改值为0x240418(对应支持音频、通知同步的车载设备类),保存后执行sudo systemctl restart bluetooth重启蓝牙服务。 - 完成和iPhone的配对绑定:
用bluetoothctl工具执行扫描、配对、连接操作,配对时iPhone端会弹出「是否允许该设备接收通知」的权限申请,必须选择允许;配对完成后进入iPhone蓝牙设置页,点击已配对的你的蓝牙设备后侧的详情按钮,确认「显示通知」开关处于开启状态。
注意:未完成这一步的前提下,任何扫描、连接操作都无法找到ANCS服务,无需浪费时间反复尝试裸连。
ANCS服务固定UUID
ANCS为苹果固定的公开BLE服务,相关UUID不需要动态扫描获取,直接使用以下固定值即可:
- ANCS根服务UUID:
7905F431-B5CE-4E99-A40F-4B1E122D00D0 - 通知源特征值UUID:
9FBF120D-6301-42D9-8C58-25E699A21DBD(iOS主动推送通知事件的通道,订阅后即可实时收到通知提醒) - 控制点特征值UUID:
69D1D8F3-45E1-49A8-95B5-08D9F2098D16(用于向iOS发送指令,比如拉取通知详情、执行通知操作) - 数据源特征值UUID:
22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB(接收你主动请求的通知详情内容,包括通知标题、正文、所属App等)
Python最小实现示例
直接使用你之前试过的bleak库即可实现,不需要额外引入其他蓝牙库,核心代码逻辑如下:
import asyncio from bleak import BleakClient # 固定ANCS相关UUID ANCS_NOTIFY_SOURCE_UUID = "9FBF120D-6301-42D9-8C58-25E699A21DBD" # 替换为配对完成后你自己iPhone的蓝牙MAC地址 IPHONE_BLE_ADDR = "XX:XX:XX:XX:XX:XX" def ancs_notify_callback(sender, raw_data): # 按ANCS公开协议解析raw_data即可 # 首字节为事件类型(新增通知/通知修改/通知移除),第2字节为事件标记,后续4字节为通知唯一ID print(f"收到iOS通知事件,原始数据: {raw_data.hex()}") async def ancs_connect(): async with BleakClient(IPHONE_BLE_ADDR) as client: # 订阅通知源通道,开始接收推送 await client.start_notify(ANCS_NOTIFY_SOURCE_UUID, ancs_notify_callback) # 保持长连接 while True: await asyncio.sleep(1) if __name__ == "__main__": asyncio.run(ancs_connect())
收到通知基础事件后,如果需要获取通知的具体内容,按照ANCS公开协议格式向控制点特征值发送查询请求,从数据源特征值读取返回内容解析即可,协议无加密、无额外鉴权。
如果你需要同步短信、iMessage等系统消息类内容,可以选择经典蓝牙MAP Profile方案:需要在BlueZ上注册MAP服务端,配对时开通MAP权限,Python端通过pydbus调用BlueZ的MAP接口即可获取内容,但该方案配置复杂度更高、资源占用更大,仅做通知展示的场景优先选择ANCS方案。
- 不要尝试在未配对绑定的状态下扫描ANCS服务,iOS对未授信设备完全隐藏该服务
- 蓝牙适配器Class值不要设置为通用电脑、手机类型,否则配对时不会触发通知权限申请,也无法获取ANCS访问权限
- 配对后如果找不到ANCS服务,直接在iPhone端忽略该设备,重新修改Class值后再配对即可解决90%以上的连接问题
- 对于已绑定的设备,iOS会使用固定的可解析私有地址,配对完成后记录bluetoothctl中显示的iPhone MAC地址即可,不需要每次重新扫描
内容的提问来源于stack exchange,提问作者identityofSine

