为了留意可能插入或拔出的耳机,请在我的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回调函数的情况下。即使使用测试来过滤错误的呼叫,它们也似乎都不是“错误的呼叫”。 我的意思是在没有我的情况下拨打或拔掉耳机。 结果这给我带来了很多麻烦。
任何人都知道为什么会发生这种情况?
答案 0 :(得分: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];