美文网首页iOS基础
关于iOS蓝牙音频断开机制

关于iOS蓝牙音频断开机制

作者: 飘零如许 | 来源:发表于2017-11-21 12:10 被阅读29次

    蓝牙连接,CoreBluetooth通过代码控制的仅仅是对于数据的传递,但是并不能处理对于蓝牙音频的判断。

    相对的在对于音频播报软件来说,当与蓝牙配对之后,尤其是导航类软件类似高德导航,在长时间的连接与息屏的情况下,会出现蓝牙音频切换到手机音频播报,但是蓝牙音频却又未断开,导致声音很小,这种状态下体验会很差。

    AVAudioSessionRouteChangeReason changeReason = [dict[AVAudioSessionRouteChangeReasonKey] intValue];

    switch (changeReason) {

    case AVAudioSessionRouteChangeReasonUnknown:

    break;

    case AVAudioSessionRouteChangeReasonNewDeviceAvailable:

    break;

    case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:

    break;

    case AVAudioSessionRouteChangeReasonCategoryChange:

    break;

    case AVAudioSessionRouteChangeReasonOverride:

    break;

    case AVAudioSessionRouteChangeReasonWakeFromSleep:

    break;

    case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:

    break;

    case AVAudioSessionRouteChangeReasonRouteConfigurationChange:

    break;

    }

    通过上面的AVFoundation 监听机制,可以判断:手机音频的切换原因

    AVAudioSessionRouteDescription *routeDescription = dict[AVAudioSessionRouteChangePreviousRouteKey];

    AVAudioSessionPortDescription  *portDescription  = [routeDescription.outputs firstObject];

    NSString *portType = portDescription.portType;

    再次判断类型:得出手机音频切换之前的音频类型:BluetoothA2DPOutput、BluetoothHFP、Speaker、Receiver...

    而我所需要的 仅仅是 蓝牙音频的机制: 因此可以进行判断:

    BOOL flag1 =  [portType isEqualToString:@"BluetoothA2DPOutput"];

    BOOL flag2 =  [portType isEqualToString:@"BluetoothHFP"];

    BOOL flag3 =  changeReason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable;

    if ((flag1 ||flag2) && flag3){

    /*之前的设备是蓝牙  在这里面进行音频播报的通道设置, 重新切换音频通道到蓝牙

    设定bool值 ,在音频播报的情况下 ,修改音频category*/

    }

    下面 我需要切换播报的category:

    typedef NS_OPTIONS(NSUInteger, AVAudioSessionCategoryOptions){

    /* MixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and  AVAudioSessionCategoryMultiRoute */

    AVAudioSessionCategoryOptionMixWithOthers = 0x1,

    /* DuckOthers is only valid with AVAudioSessionCategoryAmbient, AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */

    AVAudioSessionCategoryOptionDuckOthers = 0x2,

    /* AllowBluetooth is only valid with AVAudioSessionCategoryRecord and AVAudioSessionCategoryPlayAndRecord */

    AVAudioSessionCategoryOptionAllowBluetooth __TVOS_PROHIBITED __WATCHOS_PROHIBITED = 0x4,

    /* DefaultToSpeaker is only valid with AVAudioSessionCategoryPlayAndRecord */

    AVAudioSessionCategoryOptionDefaultToSpeaker __TVOS_PROHIBITED __WATCHOS_PROHIBITED = 0x8,

    /* InterruptSpokenAudioAndMixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */

    AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers NS_AVAILABLE_IOS(9_0) = 0x11,

    /* AllowBluetoothA2DP is only valid with AVAudioSessionCategoryPlayAndRecord */

    AVAudioSessionCategoryOptionAllowBluetoothA2DP API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0)) = 0x20,

    /* AllowAirPlay is only valid with AVAudioSessionCategoryPlayAndRecord */

    AVAudioSessionCategoryOptionAllowAirPlay API_AVAILABLE(ios(10.0), tvos(10.0)) __WATCHOS_PROHIBITED = 0x40,

    } NS_AVAILABLE_IOS(6_0);

    上面代码中,苹果api设定:AVAudioSessionCategoryOptionAllowBluetooth 需AVAudioSessionCategoryPlayAndRecord模式才可以起作用,因此 我们需要重新设定option:

    AVAudioSession *session = [AVAudioSession sharedInstance] ;

    [session setCategory:AVAudioSessionCategoryPlayAndRecord

    withOptions:AVAudioSessionCategoryOptionAllowBluetooth|

    AVAudioSessionCategoryOptionAllowBluetoothA2DP|AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers

    error:nil];

    这样就可以在每次播报的时候强制扭转音频到蓝牙,但我感觉这并不是最友好的方式,希望有人提出更加优化的方式。

    相关文章

      网友评论

        本文标题:关于iOS蓝牙音频断开机制

        本文链接:https://www.haomeiwen.com/subject/khgivxtx.html