iOS下USB-C转3.5mm适配器未插耳机却被识别为耳机,如何处理?
我通过NotificationCenter监听AVAudioSession.routeChangeNotification来获取音频路由变化,代码如下:
NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange), name: AVAudioSession.routeChangeNotification, object: nil)
我通过以下函数判断接入设备是否为耳机:
@objc private func handleRouteChange(notification: Notification) { guard let userInfo = notification.userInfo, let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt, let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else { return } switch reason { case .newDeviceAvailable: if hasHeadphones(in: session.currentRoute) { // 耳机逻辑 } else { // 扬声器逻辑 } case .oldDeviceUnavailable: if !hasHeadphones(in: session.currentRoute) { // 扬声器逻辑 } case .override: if !hasHeadphones(in: session.currentRoute) { // 扬声器逻辑 } default:() } } func hasHeadphones(in routeDescription: AVAudioSessionRouteDescription) -> Bool { return !routeDescription.outputs.filter({$0.portType == .headphones}).isEmpty }
当前遇到问题:当耳机未插入USB-C转3.5mm适配器时,routeDescription.outputs数组仍存在一个portType为.headphones的元素,导致被误判为已连接耳机。使用设备为iPad Pro(12.9英寸)第5代,iOS版本15.6.1。请问这是预期结果吗?有无可行的解决办法?
这是预期结果吗?
是的,这种情况属于iOS对部分USB-C音频适配器的识别逻辑导致的。有些USB-C转3.5mm适配器在未插入耳机时,系统仍会将其识别为"虚拟"的耳机端口,这是因为适配器本身的硬件设计或iOS的驱动适配问题,在iOS 15部分版本中这类问题比较常见。
可行的解决办法
1. 检查端口的isConnected属性
iOS 13及以上版本中,AVAudioSessionPortDescription新增了isConnected属性,可以用来判断该端口是否真正有设备连接。修改你的hasHeadphones函数:
func hasHeadphones(in routeDescription: AVAudioSessionRouteDescription) -> Bool { return routeDescription.outputs.contains { $0.portType == .headphones && $0.isConnected } }
这个属性能准确区分适配器本身和插入耳机后的状态,避免误判。
2. 结合输入端口判断
部分带麦克风的耳机会同时注册输入和输出端口,你可以额外检查输入端口中是否存在耳机类型的端口,进一步提升判断准确性:
func hasHeadphones(in routeDescription: AVAudioSessionRouteDescription) -> Bool { let hasHeadphoneOutput = routeDescription.outputs.contains { $0.portType == .headphones && $0.isConnected } let hasHeadphoneInput = routeDescription.inputs.contains { $0.portType == .headsetMic || $0.portType == .headphones } return hasHeadphoneOutput || hasHeadphoneInput }
3. 辅助结合中断通知判断
虽然不是直接解决路由识别问题,但可以监听AVAudioSession.interruptionNotification,在音频中断事件中辅助确认设备连接状态,覆盖一些边缘场景下的判断盲区。
内容的提问来源于stack exchange,提问作者Shwetal Patel

