I have added an observer for the interrupt notification when recording audio.
This works fine when performing an outgoing-call, getting an incoming call and not answering, Siri, etc..
Now my app is running in the background with the red bar at the top of the screen, and continuing the recording in the states described above is not a problem.
But when I actually answer an incoming-call. I get another AVAudioSessionInterruptionTypeBegan
notification and then when I stop the call, I never get a notification AVAudioSessionInterruptionTypeEnded
type.
I have tried using the CTCallCenter to detect when a call has started, but I am unable to restart the recording from that callback.
Does anyone know how to get the interrupt mechanism to work with an incoming call that is actually getting answered?
This is (part of) the code I am using;
CFNotificationCenterAddObserver(
CFNotificationCenterGetLocalCenter(),
this,
&handle_interrupt,
(__bridge CFStringRef) AVAudioSessionInterruptionNotification,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately );
...
static void handle_interrupt( CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo )
{
au_recorder *recorder = static_cast<au_recorder*>( observer );
NSNumber* interruptionType = [( ( __bridge NSDictionary* ) userInfo ) objectForKey:AVAudioSessionInterruptionTypeKey];
switch ( [interruptionType unsignedIntegerValue] )
{
case AVAudioSessionInterruptionTypeBegan:
{
// pause recorder without stopping recording (already done by OS)
recorder->pause();
break;
}
case AVAudioSessionInterruptionTypeEnded:
{
NSNumber* interruptionOption = [( ( __bridge NSDictionary* ) userInfo ) objectForKey:AVAudioSessionInterruptionOptionKey];
if ( interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume )
{
recorder->resume();
}
break;
}
}
}
I have tried binding the notification to either the AppDelegate, a UIViewController and a separate class, but that doesn't appear to help.
Edit
This is what I tried using the CTCallCenter, but this is very flaky. When recorder->resume()
is called from the callback, it either works, crashes violently or doesn't do anything at all until the app is put back in the foreground again manually.
callCenter = [[CTCallCenter alloc] init];
callCenter.callEventHandler = ^(CTCall *call)
{
if ([call.callState isEqualToString:CTCallStateDisconnected])
{
recorder->resume();
}
};