1

为了密切注意,在我的 iPhone 应用程序中可能插入或拔出的耳机并做出正确反应;在我的一些课程中,我使用了以下类型的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    …..
    routeChangeID=kAudioSessionProperty_AudioRouteChange;
    AudioSessionAddPropertyListener(routeChangeID,rvcHandleRouteChange,(__bridge void *)(self));
}

…….

void rvcHandleRouteChange(void *inUserData,AudioSessionPropertyID inPropertyID,
                          UInt32 inPropertyValueSize,const void *inPropertyValue)
{
    NSLog(@"Hi rvcHandleRouteChange has been called.");
    if (inPropertyID!=kAudioSessionProperty_AudioRouteChange) NSLog(@"WRONG CALL!!!");
    // Do some useful work ….
}

这似乎工作得很好,除了在没有明显原因的情况下调用 rvcHandleRouteChange 回调函数的一种情况。即使使用过滤错误呼叫的测试,它们似乎都不是“错误呼叫”。我的意思是它在没有我插入或拔出任何耳机的情况下被调用。结果,这给我带来了很多麻烦。

任何人都知道为什么会发生这种情况?

4

1 回答 1

1

1:路由更改呼叫甚至可以发生两次。例如,如果您插入耳机(相同的路线更改原因代码)。

2:一旦您将音频会话设置为活动状态,就会调用 RouteChange。这意味着至少一次。

也许您正在实施您自己的音频中断来激活/停用音频会话?

这是我的路由更改监听器,可用于任何用途(我使用 playAndRecord 类别)[更新到 iOS7]:

#pragma mark Route change listener
// *********************************************************************************************************
// *********** Route change listener ***********************************************************************
// *********************************************************************************************************
-(void)routeChanged:(NSNotification*)notification {

    NSLog(@"]-----------------[ Audio Route Change ]--------------------[");

    AVAudioSession *session = [AVAudioSession sharedInstance];

    //AVAudioSessionRouteDescription* prevRoute = [[notification userInfo] objectForKey:AVAudioSessionRouteChangePreviousRouteKey];

    // Reason
    NSInteger reason = [[[notification userInfo] objectForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (reason) {
        case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:
            NSLog(@"] Audio Route: The route changed because no suitable route is now available for the specified category.");
            break;
        case AVAudioSessionRouteChangeReasonWakeFromSleep:
            NSLog(@"] Audio Route: The route changed when the device woke up from sleep.");
            break;
        case AVAudioSessionRouteChangeReasonOverride:
            NSLog(@"] Audio Route: The output route was overridden by the app.");
            break;
        case AVAudioSessionRouteChangeReasonCategoryChange:
            NSLog(@"] Audio Route: The category of the session object changed.");
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            NSLog(@"] Audio Route: The previous audio output path is no longer available.");
            break;
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            NSLog(@"] Audio Route: A preferred new audio output path is now available.");
            break;
        case AVAudioSessionRouteChangeReasonUnknown:
            NSLog(@"] Audio Route: The reason for the change is unknown.");
            break;
        default:
            NSLog(@"] Audio Route: The reason for the change is very unknown.");
            break;
    }

    // Output
    AVAudioSessionPortDescription *output = [[session.currentRoute.outputs count]?session.currentRoute.outputs:nil objectAtIndex:0];
    if ([output.portType isEqualToString:AVAudioSessionPortLineOut]) {
        NSLog(@"] Audio Route: Output Port: LineOut");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortHeadphones]) {
        NSLog(@"] Audio Route: Output Port: Headphones");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBluetoothA2DP]) {
        NSLog(@"] Audio Route: Output Port: BluetoothA2DP");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBuiltInReceiver]) {
        NSLog(@"] Audio Route: Output Port: BuiltInReceiver");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBuiltInSpeaker]) {
        NSLog(@"] Audio Route: Output Port: BuiltInSpeaker");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortHDMI]) {
        NSLog(@"] Audio Route: Output Port: HDMI");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortAirPlay]) {
        NSLog(@"] Audio Route: Output Port: AirPlay");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBluetoothLE]) {
        NSLog(@"] Audio Route: Output Port: BluetoothLE");
    }
    else {
        NSLog(@"] Audio Route: Output Port: Unknown: %@",output.portType);
    }

    // Input
    AVAudioSessionPortDescription *input = [[session.currentRoute.inputs count] ? session.currentRoute.inputs:nil objectAtIndex:0];

    if ([input.portType isEqualToString:AVAudioSessionPortLineIn]) {
        NSLog(@"] Audio Route: Input Port: LineIn");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
        NSLog(@"] Audio Route: Input Port: BuiltInMic");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortHeadsetMic]) {
        NSLog(@"] Audio Route: Input Port: HeadsetMic");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortBluetoothHFP]) {
        NSLog(@"] Audio Route: Input Port: BluetoothHFP");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortUSBAudio]) {
        NSLog(@"] Audio Route: Input Port: USBAudio");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortCarAudio]) {
        NSLog(@"] Audio Route: Input Port: CarAudio");
    }
    else {
        NSLog(@"] Audio Input Port: Unknown: %@",input.portType);
    }

    NSLog(@"]--------------------------[  ]-----------------------------[");

}

请记住添加观察者,因为音频会话的委托也已弃用:

[[NSNotificationCenter defaultCenter] addObserver: self
                                                 selector: @selector(audioInterruption:)
                                                     name: AVAudioSessionInterruptionNotification
                                                   object: nil];
于 2013-12-24T11:28:05.817 回答