How to detect iphone is on silent mode

23,841

Solution 1

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;

Solution 2

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.

Solution 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...

Solution 4

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).

Share:
23,841
Jyotsna
Author by

Jyotsna

Updated on July 05, 2022

Comments

  • Jyotsna
    Jyotsna almost 2 years

    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.