How to programmatically sense the iPhone mute switch? How to programmatically sense the iPhone mute switch? ios ios

How to programmatically sense the iPhone mute switch?


Thanks, JPM. Indeed, the link you provide leads to the correct answer (eventually. ;) For completeness (because S.O. should be a source of QUICK answers! )...

// "Ambient" makes it respect the mute switch// Must call this once to init sessionif (!gAudioSessionInited){    AudioSessionInterruptionListener    inInterruptionListener = NULL;    OSStatus    error;    if ((error = AudioSessionInitialize (NULL, NULL, inInterruptionListener, NULL)))    {        NSLog(@"*** Error *** error in AudioSessionInitialize: %d.", error);    }    else    {        gAudioSessionInited = YES;    }}SInt32  ambient = kAudioSessionCategory_AmbientSound;if (AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (ambient), &ambient)){    NSLog(@"*** Error *** could not set Session property to ambient.");}


I answered a similar question here (link). The relevant code:

 -(BOOL)silenced {     #if TARGET_IPHONE_SIMULATOR         // return NO in simulator. Code causes crashes for some reason.         return NO;     #endif    CFStringRef state;    UInt32 propertySize = sizeof(CFStringRef);    AudioSessionInitialize(NULL, NULL, NULL, NULL);    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);    if(CFStringGetLength(state) > 0)            return NO;    else            return YES;    }


Some of the code in other answers (including the accepted answer) may not work if you aren't in the ambient mode, where the mute switch is respected.

I wrote the routine below to switch to ambient, read the switch, and then return to the settings I need in my app.

-(BOOL)muteSwitchEnabled {#if TARGET_IPHONE_SIMULATOR    // set to NO in simulator. Code causes crashes for some reason.    return NO;#endif// go back to Ambient to detect the switchAVAudioSession* sharedSession = [AVAudioSession sharedInstance];[sharedSession setCategory:AVAudioSessionCategoryAmbient error:nil];CFStringRef state;UInt32 propertySize = sizeof(CFStringRef);AudioSessionInitialize(NULL, NULL, NULL, NULL);AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);BOOL muteSwitch = (CFStringGetLength(state) <= 0);NSLog(@"Mute switch: %d",muteSwitch);// code below here is just restoring my own audio state, YMMV_hasMicrophone = [sharedSession inputIsAvailable];NSError* setCategoryError = nil;if (_hasMicrophone) {    [sharedSession setCategory: AVAudioSessionCategoryPlayAndRecord error: &setCategoryError];    // By default PlayAndRecord plays out over the internal speaker.  We want the external speakers, thanks.    UInt32 ASRoute = kAudioSessionOverrideAudioRoute_Speaker;    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,                             sizeof (ASRoute),                             &ASRoute                             );}else    // Devices with no mike don't support PlayAndRecord - we don't get playback, so use just playback as we don't have a microphone anyway    [sharedSession setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];if (setCategoryError)    NSLog(@"Error setting audio category! %@", setCategoryError);return muteSwitch;}