Manejo de interrupciones durante una llamada telefónica: el "inicio" funciona pero el "final" no funciona

La aplicación graba audio y debe dejar de grabar audio cuando hay una interrupción, como una llamada telefónica, y luego reanudar la grabación de audio cuando termina la llamada telefónica.

La aplicación actualmente se registra cuando hay una llamada telefónica, pero cuando cuelgo el teléfono, la aplicación no registra que la interrupción haya finalizado. (No tengo otras aplicaciones abiertas).

Con delegates de funciones

Vea el código a continuación en mi 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") } 

Con notifications

También traté de manejar las interrupciones con las notifications, pero el .Ended todavía no se maneja, a less que reciba una llamada telefónica y rechazo la llamada. Ver código en mi AppDelegate

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let center = NSNotificationCenter.defaultCenter() center.addObserver(self, selector:"sessionInterrupted:", name:AVAudioSessionInterruptionNotification, object:AVAudioSession.shanetworkingInstance()) //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") } } 

Soluciones relacionadas que no funcionaron para mí

  1. Solución: Agregar [[UIApplication shanetworkingApplication] beginReceivingRemoteControlEvents]; que no funcionó
    • AVAudioRecorder no grabó en segundo plano después de que finalizó la interrupción de la session de audio
    • Sesión de Audio iOS en manos
  2. Solución: use MixWithOthers , que puede funcionar para reanudar la reproducción de audio, pero no funciona en mi caso para reanudar la grabación de audio
    • Swift: cómo configurar una session de audio que se mezcla con gracia con otros (también conocido como Pod)
    • La reproducción de AVAudioPlayer no funciona después de la interrupción de FaceTime entrante.

Hipotesis actual

Mi hipótesis actual es que la interrupción "finalizada" es solo para interrupciones, como cuando recibes una llamada telefónica y rechazas la llamada, pero no si realmente retienes el teléfono, hablas un poco y luego cuelgas. Mi conjetura es que no hay forma de detectar el último caso, sin usar un teléfono con jaula.

Ampliado de una manera más amplia aquí: la notificación de interrupción de session de iOS AVAudio no funciona como se esperaba

Esta hipótesis parece verificada en las preguntas frecuentes de DropVox :

Solo una aplicación tiene control sobre el audio a la vez. Si DropVox está grabando y otra aplicación toma el control, se llama "interrupción". Cuando la interrupción termina, solo es posible que DropVox reanude la grabación si está en el primer plano 7 , por lo que advertimos contra el uso del "Record in the background "configuration.

Podría manejar las interrupciones utilizando el routing para detectar que el micrófono se está usando. Pero no creo que pueda volver a activar la grabación de audio en segundo plano, así que haría eso una vez que la aplicación vuelva a estar en primer plano.

¿Está bien?

NO activa una session de audio en applicationWillResignActive:/applicationDidBecomeActive: ¡function!

cuando llegó la llamada telefónica, el sistema posee la session de audio, en este momento si llama a la function [[AVAudioSession shanetworkingInstance] setActive:YES error:&error] en la applicationWillResignActive:/applicationDidBecomeActive: [[AVAudioSession shanetworkingInstance] setActive:YES error:&error] applicationWillResignActive:/applicationDidBecomeActive: function, su aplicación será la propietaria de la grabación de audio (en realidad debería fallar a una session de audio activa cuando la llamada telefónica, pero no sé por qué se vuelve verdadera) y no recibirá la interrupción final.