【问题标题】:How to detect if a bluetooth headset plugged or not IOS 8?如何检测蓝牙耳机是否插入 IOS 8?
【发布时间】:2015-05-09 20:01:15
【问题描述】:

在我的项目中,我使用AVAudioSession 来检测任何耳机是否插入或拔出。但在这种情况下,我无法检测到蓝牙设备何时插入。这是我的耳机状态代码。

 - (void)audioRouteChangeListenerCallback:(NSNotification*)notification
    {

    NSDictionary *interuptionDict = notification.userInfo;

    NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];

    switch (routeChangeReason) {

        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            //NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");

            NSLog(@"Headphone/Line plugged in");

            [_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-on.png"] forState:UIControlStateNormal];

            _headSetState=YES;

            break;

        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");

            NSLog(@"Headphone/Line was pulled. Stopping player....");

             [_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-off.png"] forState:UIControlStateNormal];
            if(_isPlaying==YES)
            {


            [self.player pause];

            [_audioButtonOutlet setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];

            _isPlaying=NO;

            }
            _headSetState=NO;

            break;

        case AVAudioSessionRouteChangeReasonCategoryChange:
            // called at start - also when other audio wants to play
            NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");


            break;
    }



- (BOOL)isHeadsetPluggedIn

{

    AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance] currentRoute];
    for (AVAudioSessionPortDescription* desc in [route outputs]) {

        if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones])
        {
        [_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-on.png"] forState:UIControlStateNormal];
            _headSetState=YES;
            return YES;
        }
        else
        {
    [_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-off.png"] forState:UIControlStateNormal];
            _headSetState=NO;
            return NO;

        }
    }


    return NO;
}

}


- viewWillAppear  {

 [AVAudioSession sharedInstance];

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil];

[self isHeadsetPluggedIn];

}

那么如何检测蓝牙耳机是否插入 iOS 8?

【问题讨论】:

标签: bluetooth ios8 headset audiosession


【解决方案1】:

您可以检测当前活动的蓝牙输出设备(而不是输入设备)

Swift 代码:

import AVFoundation
func bluetoothAudioConnected() -> Bool{
  let outputs = AVAudioSession.sharedInstance().currentRoute.outputs
  for output in outputs{
    if output.portType == AVAudioSessionPortBluetoothA2DP || output.portType == AVAudioSessionPortBluetoothHFP || output.portType == AVAudioSessionPortBluetoothLE{
      return true
    }
  }
  return false
}

蓝牙设备基于以下问题:What's the difference among AVAudioSessionPortBluetoothHFP, A2DP and LE?

希望对大家有所帮助


为 Swift 5.1 编辑(感谢 iago849 的修复)

var bluetoothDeviceConnected: Bool {
    !AVAudioSession.sharedInstance().currentRoute.outputs.compactMap {
        ($0.portType == .bluetoothA2DP ||
        $0.portType == .bluetoothHFP ||
        $0.portType == .bluetoothLE) ? true : nil
    }.isEmpty
}

【讨论】:

  • 这不会告诉你是否正在处理耳机;只是一些任意的蓝牙音频设备。
  • for (swift 5.2) 检查是否连接了有线耳机,仅使用:if output.portType == AVAudioSession.Port.headphones { }
  • 酷,我的朋友,当启用输入是不可接受的(例如,airpods 中的音频质量受到很大影响)时,对于那些人来说更好的方法。我希望我能给你 10 票
  • 您的 5.1 解决方案显然是错误的,因为它总是会返回 true - 即使数组包含错误
【解决方案2】:

我能够使用以下方法检测当前是否连接了蓝牙耳机 (HFP) 设备:

NSArray *arrayInputs = [[AVAudioSession sharedInstance] availableInputs];
for (AVAudioSessionPortDescription *port in arrayInputs)
{
    if ([port.portType isEqualToString:AVAudioSessionPortBluetoothHFP])
    {
        bHas = YES;
        break;
    }
}

但是,您的 AVAudioSession 类别必须设置为 AVAudioSessionCategoryPlayAndRecord 才能正常工作。如果不是,即使连接了 HFP 设备,该端口也不会显示在列表中。

【讨论】:

    【解决方案3】:

    您可以使用 routeChangeNotification 检测它:

        func activateHeadPhonesStatus(){
            NotificationCenter.default.addObserver(self, selector: #selector(audioRouteChangeListener(_:)), name: AVAudioSession.routeChangeNotification, object: nil)
        }
        
        @objc func audioRouteChangeListener(_ notification:Notification) {
            guard let userInfo = notification.userInfo,
                  let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
                  let reason = AVAudioSession.RouteChangeReason(rawValue:reasonValue) else {
                return
            }
            if reason == .newDeviceAvailable {
                let session = AVAudioSession.sharedInstance()
                for output in session.currentRoute.outputs where output.portType == AVAudioSession.Port.bluetoothA2DP {
                    print("Bluetooth Headphone Connected")
                    break
                }
            }
        }
    

    【讨论】:

    • @famfamfam 你能说得更具体点吗?
    • 对不起兄弟,在 1 天不睡觉后,我评论了错误的标签,但我希望你能在这里帮助我:stackoverflow.com/questions/66631995/…,提前谢谢
    猜你喜欢
    • 1970-01-01
    • 2013-04-17
    • 2015-12-22
    • 2012-05-27
    • 2011-04-04
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多