Как я могу определить, подключен ли HFP или A2DP в iOS?

Я работаю над проектом, который может воспроизводить музыку через устройство HFP. Но вот проблема, которую я хочу определить, подключен ли HFP или A2DP при воспроизведении музыки.

Теперь я использую для этого фреймворк AVFoundation. Вот код:

- (BOOL)isConnectedToBluetoothPeripheral
{
    BOOL isMatch = NO;
    NSString* categoryString = [AVAudioSession sharedInstance].category;
    AVAudioSessionCategoryOptions categoryOptions = [AVAudioSession sharedInstance].categoryOptions;
    if ((![categoryString isEqualToString:AVAudioSessionCategoryPlayAndRecord] &&
         ![categoryString isEqualToString:AVAudioSessionCategoryRecord]) ||
        categoryOptions != AVAudioSessionCategoryOptionAllowBluetooth)
    {
        NSError * error = nil;
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
                                         withOptions:AVAudioSessionCategoryOptionAllowBluetooth
                                               error:&error];
        if (error) {
            [[AVAudioSession sharedInstance] setCategory:categoryString
                                             withOptions:categoryOptions
                                                   error:&error];
            return isMatch;
        }
    }
    
        NSArray * availableInputs = [AVAudioSession sharedInstance].availableInputs;
        for (AVAudioSessionPortDescription *desc in availableInputs)
        {
            if ([[desc portType] isEqualToString:AVAudioSessionPortBluetoothA2DP] || [[desc portType] isEqualToString:AVAudioSessionPortBluetoothHFP])
            {
                    isMatch = YES;
                    break;
            }
        }
        if (!isMatch)
        {
            NSArray * outputs = [[[AVAudioSession sharedInstance] currentRoute] outputs];
            
            for (AVAudioSessionPortDescription * desc in outputs)
            {
                if ([[desc portType] isEqualToString:AVAudioSessionPortBluetoothA2DP] || [[desc portType] isEqualToString:AVAudioSessionPortBluetoothHFP])
                {
                        isMatch = YES;
                        break;
                }
            }
        }
        
        NSError * error = nil;
        [[AVAudioSession sharedInstance] setCategory:categoryString
                                         withOptions:categoryOptions
                                               error:&error];
    
        return isMatch;
}

Это работает хорошо, но вызывает другую проблему: во время воспроизведения музыки использование этого метода для обнаружения подключения HFP приведет к прерыванию воспроизведения музыки примерно на две секунды.

Поэтому я попробовал другой способ, который может уменьшить эффект обнаружения подключения HFP. я использую флаг

static BOOL isHFPConnectedFlag

Чтобы указать, подключен ли HFP или A2DP. Я использую предыдущий метод, чтобы обнаружить соединение только один раз (при запуске приложения) и сохранить результат в isHFPConnectedFlag. Более того, я наблюдаю, как AudioSessionRouteChange синхронизирует состояние подключения:

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

Когда причина изменения маршрута AVAudioSessionRouteChangeReasonNewDeviceAvailable или AVAudioSessionRouteChangeReasonOldDeviceUnavailable, я могу узнать, подключен или отключен HFP. К сожалению, когда я подключаю какой-либо HFP в своем iPhone, система не публикует это уведомление, поэтому я не могу определить подключение в этой ситуации.

Кто-нибудь знает причину или лучший способ реализовать это (обнаружение соединения HFP без прерывания воспроизведения музыки)?


person EricCheung    schedule 11.05.2016    source источник


Ответы (2)


вы можете использовать, как это!

    -(BOOL) bluetoothDeviceA2DPAvailable {

    BOOL available = NO;
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    AVAudioSessionRouteDescription *currentRoute = [audioSession currentRoute];

    for (AVAudioSessionPortDescription *output in currentRoute.outputs) {
        if (([[output portType] isEqualToString:AVAudioSessionPortBluetoothA2DP] ||
             [[output portType] isEqualToString:AVAudioSessionPortBluetoothHFP])) {
            available = YES;
            break;
        }
    }
    return available;
}
person Mk-Lee    schedule 11.10.2016

Версия Swift 5:

func bluetoothDeviceHFPAvailable() -> Bool {
    let audioSession = AVAudioSession.sharedInstance()
    let currentRoute = audioSession.currentRoute

    for output in currentRoute.outputs {
        if output.portType == .bluetoothHFP || output.portType == .bluetoothA2DP {
            return true
        }
    }

    return false
}
person Shebuka    schedule 22.05.2020