19

I am developing an application. In that i want to detect through coding that "is iPhone on silent mode or not?". I am developing it by using cocoa with Objective-C.

If anyone knows it kindly reply.

iDeveloper
  • 940
  • 1
  • 10
  • 45
Jyotsna
  • 4,021
  • 4
  • 22
  • 25

4 Answers4

20

The reason Pirripli's code does not work is that the simulator does not support the test and the code does not check for errors. Corrected code would look like:

CFStringRef state = nil;
UInt32 propertySize = sizeof(CFStringRef);
AudioSessionInitialize(NULL, NULL, NULL, NULL);
OSStatus status = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);

if (status == kAudioSessionNoError)
{
    return (CFStringGetLength(state) == 0);   // YES = silent
}
return NO;
Neil
  • 601
  • 7
  • 16
  • 2
    doesn't work on iPhone 4 iOS 5 :( .. state = "speaker", i think – Mazyod Oct 16 '11 at 13:42
  • Correct, does not work on iOS 5, it turns out that Apple never intended it to be used this way. My app no longer attempts to find out the state of the mute switch. The app outputs audio and if the user has the mute switch on then the audio does not sound. The app also have a preference for vibrate and if the user has that turned on then the app vibrates in addition to audio. So the user has complete control and the app does not need to know the status of the switch. – Neil Jan 24 '12 at 16:07
  • @Neil, you say that your app "no longer attempts to find out the state of the mute switch" but then "if the user has the mute switch on then the audio does not sound". Doesn't that mean that you're monitoring the mute switch? Which category (or categories) are you using? – ari gold Nov 25 '12 at 01:40
  • @ari gold, I don't monitor the mute switch. if the user has mute turned on then no sound emerges, if off it does, my app does not care. – Neil Dec 30 '12 at 19:24
4

It's possible by testing for a NULL audio route using AudioToolBox:

UInt32 routeSize = sizeof (CFStringRef);
CFStringRef route;

AudioSessionGetProperty (
                         kAudioSessionProperty_AudioRoute,
                         &routeSize,
                         &route
                        );

if (route == NULL) {
    NSLog(@"Silent switch is on");
}

If route is NULL then there's no available audio outputs. If it's "Headset" or "Headphones" then the silent ringer switch could still be on. However, it will never be on when it's set to "Speaker".

You're probably best testing for this in your audio route change property listener, which is set below:

AudioSessionAddPropertyListener (
                                 kAudioSessionProperty_AudioRouteChange,
                                 audioRouteChangeListenerCallback,
                                 self
                                 );

Note: If you're doing anything funky like overriding audio routes, then this answer may not apply.

Setting up and tearing down an audio session in its entirety is probably beyond the scope of this answer.

Alastair Stuart
  • 4,165
  • 3
  • 36
  • 33
3

For completeness, building off this link from Dan Bon, I implement the following method to solve this problem in my apps. One thing to note is that the code checks for the iPhone simulator first - executing the below code will crash the simulator. Anyone know why?

-(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;

}

Declaring this right in the view controller, you'd simply check

if ([self silenced]) {
     NSLog(@"silenced");

else {
     NSLog(@"not silenced");
}

Or, obviously, you could declare it in some kind of helper class. A more elegant solution might be a category addition on UIApplication or some such other class...

Chris Ladd
  • 2,795
  • 1
  • 29
  • 22
  • AudioSessionGetProperty is deprecated now. There is [AVAudioSession sharedInstance].currentRoute to get currentRoute, but even using AVAudioSessionCategoryAmbient do not allow to get state of hardware silence switch. – slamor Dec 11 '14 at 14:53
1

You can use Audio Route property as suggested by the previous answers, but keep in mind that: - It works only if the Audio Category is AmbientSound - You should not initialize Audio Session more than once in your app (see Audio Session Programming Guide) - You should release those CFStringRef to avoid mem leaks

In case the current audio category is not AmbientSound though, you can think of changing it temporarily, perform the check on Audio Route property, and then restoring the original Audio Category.

Note that changing Audio Category will restore the default Audio Route for that category, given the current hardware configuration (i.e. whether there are headphones plugged in or not, etc).

giavac
  • 988
  • 7
  • 22