I am writing a very simple application that plays sound when a button is pressed. Since this button does not make much sense when the device is set to silent, I want to turn it off when the device’s sound volume is zero. (And subsequently, it can be reused when the volume is twisted again.)
I am looking for a working (and safe for AppStore) way to determine the current volume level and receive a notification / callback when the volume level changes. I do not want to change the volume setting.
All this is implemented in my ViewController , where this button is used. I tested this with iPhone 4 with iOS 4.0.1 and 4.0.2, as well as with iPhone 3G 4.0.1. Built with iOS SDK 4.0.2 with llvm 1.5. (Using gcc or llvm-gcc does not improve anything.) There are no problems, no errors, or warnings during the implementation of the build. The static analyzer is also happy.
Here is what I have tried so far, all without success.
Following Apple's audio documentation, I have to register an AudioSessionAddPropertyListener for kAudioSessionProperty_CurrentHardwareOutputVolume , which should work as follows:
// Registering for Volume Change notifications AudioSessionInitialize(NULL, NULL, NULL, NULL); returnvalue = AudioSessionAddPropertyListener ( kAudioSessionProperty_CurrentHardwareOutputVolume , audioVolumeChangeListenerCallback, self );
returnvalue 0 , which means that callback registration has been completed.
Unfortunately, I never get a callback to my audioVolumeChangeListenerCallback function when I press the volume buttons on my device, the headset clicks or flips the switch without ringing.
When using the same registration code for kAudioSessionProperty_AudioRouteChange (which is used as a similar sample project in WWDC video, documentation for developers and on numerous sites on networks), I really get a callback when changing the audio track (by connecting / disconnecting the headset or docking the device )
A user named Doug opened a stream called changed iPhone volume to volumes already max , where he claimed that he was using this method successfully (unless the volume changed, because it was already set to maximum). However, this does not work for me.
Another way I tried is to register at NSNotificationCenter like this.
// sharedAVSystemController AudioSessionInitialize(NULL, NULL, NULL, NULL); NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
This should notify my volumeChanged method of any changes to SystemVolume , but in fact it is not.
Since a common opinion tells me that if someone works too hard to achieve something with Cocoa, then someone is doing something fundamentally wrong. I expect to miss something. It's hard to believe that there is no easy way to get the current volume level, but I could not find it using the Apple documentation, sample code, Google, Apple Developer forums or watching WWDC 2010 videos.