Как определить, подключена ли Bluetooth-гарнитура IOS 8 или нет?

В своем проекте я использую AVAudioSession для обнаружения подключенных или отключенных наушников. Но в этом случае я не могу определить, подключено ли устройство Bluetooth. Вот мой код состояния наушников.

 - (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];

}

Итак, как я могу определить, подключена ли Bluetooth-гарнитура iOS 8 или нет?


person Mustafa Sait Demirci    schedule 08.03.2015    source источник
comment
Решаю проблему этим ответом. stackoverflow.com/a/44026312/935043   -  person Pedro Silva    schedule 17.05.2017


Ответы (3)


Мне удалось определить, подключена ли в настоящее время bluetooth-гарнитура (HFP), используя следующее:

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

Однако ваша категория AVAudioSession должна быть установлена ​​как AVAudioSessionCategoryPlayAndRecord, чтобы это работало. В противном случае порт не будет отображаться в списке, даже если устройство HFP подключено.

person Adam    schedule 28.03.2015

Вы можете обнаружить активные в данный момент устройства вывода Bluetooth (вместо устройств ввода)

Быстрый код:

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
}

В основе устройств Bluetooth лежит следующий вопрос: В чем разница между AVAudioSessionPortBluetoothHFP, A2DP и 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
}
person Gerrit Post    schedule 17.02.2016
comment
Это не скажет вам, имеете ли вы дело с гарнитурой; просто какое-то произвольное аудиоустройство Bluetooth. - person mrgrieves; 12.08.2017
comment
for (swift 5.2), чтобы проверить, подключена ли проводная гарнитура или нет, просто используйте: if output.portType == AVAudioSession.Port.headphones {} - person Debashish Das; 20.07.2020
comment
круто, друг мой, гораздо лучший подход для тех, когда включение ввода недопустимо (например, качество звука в airpods сильно страдает). Хотел бы я дать вам 10 голосов за - person iago849; 03.05.2021
comment
ваше решение 5.1 явно НЕПРАВИЛЬНО, потому что оно всегда будет возвращать истину - даже если массив содержит ложные - person iago849; 04.05.2021
comment
спасибо за исправление! - person iago849; 05.05.2021

Вы можете обнаружить это с помощью 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
            }
        }
    }
person Sasan Log    schedule 01.10.2020
comment
@famfamfam не могли бы вы быть более конкретными? - person Sasan Log; 17.03.2021
comment
извини, братан, через 1 день без сна я прокомментировал неправильную вкладку, но я хочу, чтобы ты мог мне помочь здесь: stackoverflow.com/questions/66631995/, заранее спасибо - person famfamfam; 17.03.2021