Adrienne
Adrienne

Reputation: 2680

Handling interruptions during a phone call - the "begin" works but the "end" doesn't

The app records audio and should stop recording audio when there is an interruption, such as a phone call, and then resume recording audio when the phone call ends.

The app currently registers when there is a phone call, but when I hang up the phone, the app does not register that the interruption has ended. (I have no other apps open).

With function delegates

See code below in my ViewController.

func audioRecorderBeginInterruption(recorder: AVAudioRecorder){
    print("* * * * * * * inside begin interruption")}

func audioRecorderEndInterruption(recorder: AVAudioRecorder, withFlags flags: Int) {
    // THIS NEVER PRINTS, EVEN WHEN PHONE IS HUNG UP
    print("* * * * * * * inside end interruption")
}

With notifications

I've also tried to handle interruptions with notifications, but the .Ended is still not handled, unless I receive a phone call and I decline the call. See code in my AppDelegate

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let center = NSNotificationCenter.defaultCenter()

        center.addObserver(self,
            selector:"sessionInterrupted:",
            name:AVAudioSessionInterruptionNotification,
            object:AVAudioSession.sharedInstance()) //self.myViewController.audioSession)


        return true
    }



 func sessionInterrupted(notification: NSNotification){
                if let typeValue = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? NSNumber{
                    if let type = AVAudioSessionInterruptionType(rawValue: typeValue.unsignedLongValue){
                        if type == .Began{
                            print("interruption: began")
                        } else{
                            // THIS ALSO NEVER PRINTS
                            print("interruption: ended")
                        }
        }

Related Solutions that did not work for me

  1. Solution: Adding [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; which did not work
  2. Solution: Use MixWithOthers, which may work for resuming playing audio, but does not work in my case for resuming recording audio

Current Hypothesis

My current hypothesis is that the "Ended" interruption is only for interruptions such as when you get a phone call, and you decline the call, but not for if you actually pick up the phone, talk for a bit, and then hang up. My guess is there is no way to detect the latter case, without using a jailbroken phone.

Expanded on in a broader way here: iOS AVAudioSession interruption notification not working as expected

This hypothesis appears to be verified in DropVox's FAQ:

Only one app has control over audio at a time. If DropVox is recording and another app takes control, that’s called an “interruption.” When the interruption is over, it’s only possible for DropVox to resume recording if its in the foreground7, which is why we caution against using the “Record in the background” setting.

I could possibly handle the interruptions by using routing to detect the microphone is being used. But I don't think that I can re-activate audio recording in the background, so I would do that once the app is back in the foreground.

Is that right?

Upvotes: 4

Views: 3678

Answers (1)

chaoyuan899
chaoyuan899

Reputation: 1

DO NOT active audiosession in applicationWillResignActive:/applicationDidBecomeActive: function !

when the phone call reached, the system own the audiosession,at this time if you call function [[AVAudioSession sharedInstance] setActive:YES error:&error] in the applicationWillResignActive:/applicationDidBecomeActive: function ,your app will own the audiosession back(actually it should be fail to active audiosession when the phone call,but I don't know why it return true) and will not receive the end interruption.

Upvotes: -2

Related Questions