volumen tonos tono suena silenciar recibe para llamadas llamada las escuchan cómo como cambiar bajar baja apple ios iphone audio ios4 volume

ios - tonos - silenciar apple watch



¿Cómo obtener el nivel de volumen de audio y el volumen cambiado las notificaciones en iOS? (9)

Estoy escribiendo una aplicación muy simple que reproduce un sonido al presionar un botón. Como ese botón no tiene mucho sentido cuando el dispositivo está configurado para silenciar, quiero desactivarlo cuando el volumen de audio del dispositivo es cero. (Y luego vuelva a habilitarlo cuando el volumen vuelva a subir).

Estoy buscando una forma de trabajo (y AppStore segura) para detectar la configuración de volumen actual y obtener una notificación / devolución de llamada cuando el nivel de volumen cambia. No quiero alterar la configuración de volumen .

Todo esto se implementa en mi ViewController donde se usa dicho botón. Lo probé con un iPhone 4 con iOS 4.0.1 y 4.0.2 y con un iPhone 3G con 4.0.1. Desarrollado con iOS SDK 4.0.2 con llvm 1.5. (El uso de gcc o llvm-gcc no mejora nada). No hay problemas durante la implementación de la compilación en ambos sentidos, ni errores ni advertencias. El analizador estático también está contento.

Esto es lo que he intentado hasta ahora, todo sin ningún éxito.

Siguiendo la documentación de los servicios de audio de Apple, debo registrar un AudioSessionAddPropertyListener para kAudioSessionProperty_CurrentHardwareOutputVolume que debería funcionar así:

// Registering for Volume Change notifications AudioSessionInitialize(NULL, NULL, NULL, NULL); returnvalue = AudioSessionAddPropertyListener ( kAudioSessionProperty_CurrentHardwareOutputVolume , audioVolumeChangeListenerCallback, self );

returnvalue es 0 , lo que significa que el registro de la devolución de llamada funcionó.

Tristemente, nunca recibo una devolución de llamada a mi función audioVolumeChangeListenerCallback cuando audioVolumeChangeListenerCallback los botones de volumen en mi dispositivo, el clicker de los auriculares o cambio el interruptor silencioso.

Cuando kAudioSessionProperty_AudioRouteChange exactamente el mismo código para registrar kAudioSessionProperty_AudioRouteChange (que se utiliza como un proyecto de ejemplo análogo en videos WWDC, documentación del desarrollador y en numerosos sitios en interwebs), en realidad obtengo una devolución de llamada cuando cambio la ruta de audio (conectando / desconectando unos auriculares o acoplando el dispositivo).

Un usuario llamado Doug abrió un hilo titulado " Volumen del iPhone cambió el evento por el volumen ya máximo", donde afirmó que está usando de esta manera (a menos que el volumen no cambie porque ya está configurado al máximo). Aún así, no funciona para mí.

Otra forma que he intentado es registrarme en NSNotificationCenter así.

// sharedAVSystemController AudioSessionInitialize(NULL, NULL, NULL, NULL); NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];

Esto debería notificar a mi método el volumeChanged de cualquier cambio de SystemVolume pero en realidad no lo hace.

Como la creencia común me dice que si uno está trabajando demasiado duro para lograr algo con Cocoa, uno está haciendo algo fundamentalmente erróneo. Estoy esperando perder algo aquí. Es difícil creer que no hay una forma sencilla de obtener el nivel de volumen actual, pero no he podido encontrar uno con la documentación de Apple, el código de muestra, Google, los foros de desarrolladores de Apple o viendo videos de WWDC 2010.


¿Alguna posibilidad de que haya hecho su firma incorrecta para el método volumeChanged:? Esto funcionó para mí, arrojado a mi delegado de aplicaciones:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; } - (void)volumeChanged:(NSNotification *)notification { float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue]; // Do stuff with volume }

Mi volumeChanged: método se acelera cada vez que se presiona el botón, incluso si el volumen no cambia como resultado (porque ya está en max / min).


¿Comenzó la sesión de audio con AudioSessionSetActive?


Añadiendo a la respuesta de Stuart usando AVAudioSession para dar cuenta de algunos cambios en Swift 3. Espero que el código aclare dónde va cada componente.

override func viewWillAppear(_ animated: Bool) { listenVolumeButton() } func listenVolumeButton(){ let audioSession = AVAudioSession.sharedInstance() do{ try audioSession.setActive(true) let vol = audioSession.outputVolume print(vol.description) //gets initial volume } catch{ print("Error info: /(error)") } audioSession.addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil) } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "outputVolume"{ let volume = (change?[NSKeyValueChangeKey.newKey] as NSNumber)?.floatValue print("volume " + volume!.description) } } override func viewWillDisappear(_ animated: Bool) { audioSession.removeObserver(self, forKeyPath: "outputVolume") }


Creo que depende de otra implementación. Si, por ejemplo, utiliza el control deslizante para controlar el volumen del sonido, puede realizar una acción de control mediante UIControlEventValueChanged y si obtiene un valor de 0, puede establecer el botón oculto o deshabilitado.

Algo como:

[MusicsliderCtl addTarget:self action:@selector(checkZeroVolume:)forControlEvents:UIControlEventValueChanged];

donde void checkZeroVolume podría hacer la comparación del volumen real ya que se activa después de cualquier cambio de volumen.


La API de AudioSession utilizada aquí por algunas respuestas ha quedado obsoleta a partir de iOS 7. Fue reemplazada por AVAudioSession , que expone una propiedad outputVolume para el volumen de salida de todo el sistema. Esto se puede observar usando KVO para recibir notificaciones cuando el volumen cambia, como se señala en la documentación:

Un valor en el rango de 0.0 a 1.0, donde 0.0 representa el volumen mínimo y 1.0 representa el volumen máximo.

El volumen de salida de todo el sistema se puede configurar directamente solo por el usuario; para proporcionar control de volumen en su aplicación, use la clase MPVolumeView.

Puede observar cambios en el valor de esta propiedad mediante el uso de la observación de valores-clave.

Debes asegurarte de que la sesión de audio de tu aplicación esté activa para que funcione:

let audioSession = AVAudioSession.sharedInstance() do { try audioSession.setActive(true) startObservingVolumeChanges() } catch { print(“Failed to activate audio session") }

Entonces, si todo lo que necesita es consultar el volumen del sistema actual:

let volume = audioSession.outputVolume

O podemos recibir notificaciones de cambios como estos:

private struct Observation { static let VolumeKey = "outputVolume" static var Context = 0 } func startObservingVolumeChanges() { audioSession.addObserver(self, forKeyPath: Observation.VolumeKey, options: [.Initial, .New], context: &Observation.Context) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { if context == &Observation.Context { if keyPath == Observation.VolumeKey, let volume = (change?[NSKeyValueChangeNewKey] as? NSNumber)?.floatValue { // `volume` contains the new system output volume... print("Volume: /(volume)") } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } }

No te olvides de dejar de observar antes de ser desasignado:

func stopObservingVolumeChanges() { audioSession.removeObserver(self, forKeyPath: Observation.VolumeKey, context: &Observation.Context) }


Swift 3 versión de la excelente respuesta de Stuart:

let audioSession = AVAudioSession.sharedInstance() do { try audioSession.setActive(true) startObservingVolumeChanges() } catch { print("Failed to activate audio session") } let volume = audioSession.outputVolume private struct Observation { static let VolumeKey = "outputVolume" static var Context = 0 } func startObservingVolumeChanges() { audioSession.addObserver(self, forKeyPath: Observation.VolumeKey, options: [.Initial, .New], context: &Observation.Context) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { if context == &Observation.Context { if keyPath == Observation.VolumeKey, let volume = (change?[NSKeyValueChangeNewKey] as? NSNumber)?.floatValue { // `volume` contains the new system output volume... print("Volume: /(volume)") } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } }


Swift 4

func startObservingVolumeChanges() { avAudioSession.addObserver(self, forKeyPath: Observation.VolumeKey, options: [.initial, .new], context: &Observation.Context) } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if context == &Observation.Context { if keyPath == Observation.VolumeKey, let volume = (change?[NSKeyValueChangeKey.newKey] as? NSNumber)?.floatValue { print("/(logClassName): Volume: /(volume)") } } else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) } } func stopObservingVolumeChanges() { avAudioSession.removeObserver(self, forKeyPath: Observation.VolumeKey, context: &Observation.Context) }

y luego llamas

var avAudioSession = AVAudioSession.sharedInstance() try? avAudioSession.setActive(true) startObservingVolumeChanges()


Vaya a ajustes-> sonidos y marque ''Cambiar con botones''. Si está apagado, el volumen del sistema no cambiará al presionar los botones de volumen. Tal vez esa es la razón por la que no te notificaron.


-(float) getVolumeLevel { MPVolumeView *slide = [MPVolumeView new]; UISlider *volumeViewSlider; for (UIView *view in [slide subviews]){ if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) { volumeViewSlider = (UISlider *) view; } } float val = [volumeViewSlider value]; [slide release]; return val; }

Eso debería obtener el nivel de volumen actual. 1 es el volumen máximo, 0 no es volumen. Nota: no es necesario mostrar elementos de IU para que esto funcione. También tenga en cuenta que el nivel de volumen actual es relativo a los auriculares o altavoces (lo que significa que los dos niveles de volumen son diferentes y esto le proporciona el dispositivo que esté utilizando actualmente. Esto no responde a su pregunta sobre la recepción de notificaciones cuando cambia el volumen.