2

I've been looking for a long time, posting here as a final try before giving up. I want to detect if I'm currently on Silent mode or not.

I found a workaround (playing a fake sound and checking the completion) that works fine but only when I'm not in AVAudioSessionCategoryPlayAndRecord mode. This is precisely on a screen where I can record audio and video that I want to achieve this in order to know whether I should play UI sounds or not.

To sum up, I trying to find a way to detect silent mode when on AVAudioSessionCategoryPlayAndRecord mode.

mfaani
  • 33,269
  • 19
  • 164
  • 293
nicolas
  • 234
  • 4
  • 11
  • does this help? http://stackoverflow.com/a/16474863/655548 – gvuksic Mar 15 '16 at 10:27
  • Yes, thank you. This is why I think I'm trying to do something impossible... But still looking for some clever tricks that could make it possible! – nicolas Mar 15 '16 at 10:52

1 Answers1

1

Here is a solution that attempts reading the switch by switching the audio session category briefly to SoloAmbient (a category that does respect the silent switch) - reading the switch - and then switching back. this might be the best approach for you.

if swapping audio session category would interfere with your app, i would suggest perhaps conduct a check before playing audio and use the value you detect then react to silent switch on/off. It is a work around but it should give you some information.

switch to ambient category, determine if the silent switch is on, then switch session back to the audio settings I require. You will need to work out what audio session category you need and swap to that after you determine if the switch is on.

-(BOOL)muteSwitchEnabled {

    #if TARGET_IPHONE_SIMULATOR
    // set to NO in simulator. Code causes crashes for some reason.
    return NO;
    #endif

    // switch to Ambient to detect the switch
    AVAudioSession* 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),m&ASRoute);
    } else {
        // Devices with no mic 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;
    }
}
Natalia
  • 1,308
  • 16
  • 23