Detecting Silent Switch in iOS 7 issue

2019-02-11 11:17发布

问题:

I am using following code to check iPhone silent switch is ON or OFF :-

if (self)
   {
    self.detector = [SharkfoodMuteSwitchDetector shared];
    CheckInViewController* sself = self;
    self.detector.silentNotify = ^(BOOL silent)
       {
        [sself.silentSwitch setOn:silent animated:YES];
      };
   }

It works fine in iOS 6 and below but in iOS 7 it always gives TRUE value. So, Please any one tell, how to resolve this issue.

Thanks in advance.

回答1:

It doesn't work in iOS 7, and it never really worked in iOS 6 if you look at why it doesn't work in iOS 7. This solution is based on the same code, so all credit to the original author though.

  1. Keep mute.caf from your SharkfoodMuteSwitchDetector.
  2. Create a new class, called HASilentSwitchDetector (or whatever), or replace the code in SharkfoodMuteSwitchDetector.

In the header file:

#import <AudioToolbox/AudioToolbox.h>

typedef void(^HASilentSwitchDetectorBlock)(BOOL success, BOOL silent);

@interface HASilentSwitchDetector : NSObject

+ (void)ifMute:(HASilentSwitchDetectorBlock)then;

@end

In the implementation file:

#import "HASilentSwitchDetector.h"

void MuteSoundPlaybackComplete(SystemSoundID ssID, void *clientData)
{
    //Completion
    NSDictionary *soundCompletion = CFBridgingRelease(clientData);

    //Mute
    NSTimeInterval interval = [soundCompletion[@"interval"] doubleValue];
    NSTimeInterval elapsed = [NSDate timeIntervalSinceReferenceDate] - interval;
    BOOL isMute = elapsed < 0.2; // mute.caf is .2s long...

    //Then
    HASilentSwitchDetectorBlock then = soundCompletion[@"then"];
    then(YES, isMute);

    //Cleanup
    SystemSoundID soundID = [soundCompletion[@"soundID"] integerValue];
    AudioServicesRemoveSystemSoundCompletion(soundID);
    AudioServicesDisposeSystemSoundID(soundID);
}

@implementation HASilentSwitchDetector

+ (void)ifMute:(HASilentSwitchDetectorBlock)then
{
    //Check
    if ( !then ) {
        return;
    }

    //Create
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"mute" withExtension:@"caf"];
    SystemSoundID soundID;
    if ( AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID) == kAudioServicesNoError ) {
        //UI Sound
        UInt32 yes = 1;
        AudioServicesSetProperty(kAudioServicesPropertyIsUISound, sizeof(soundID), &soundID,sizeof(yes), &yes);

        //Callback
        NSDictionary *soundCompletion = @{@"then" : [then copy], @"soundID" : @(soundID), @"interval" : @([NSDate timeIntervalSinceReferenceDate])};
        AudioServicesAddSystemSoundCompletion(soundID, CFRunLoopGetMain(), kCFRunLoopDefaultMode, MuteSoundPlaybackComplete, (void *)CFBridgingRetain(soundCompletion));

        //Play
        AudioServicesPlaySystemSound(soundID);
    } else {
        //Fail
        then(NO, NO);
    }
}

@end

Use like so:

[HASilentSwitchDetector ifMute:^(BOOL success, BOOL silent) {
    if ( success ) {
        if ( ![[NSUserDefaults standardUserDefaults] boolForKey:forKey:kHasShownMuteWarning] && silent ) {
            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kHasShownMuteWarning];
            [[[UIAlertView alloc] initWithTitle:[@"Mute Warning" localized] message:[NSString stringWithFormat:[@"This %@'s mute switch is on.  To ensure your alarm will be audible, unmute your device." localized], [[[UIDevice currentDevice] isiPad]? @"iPad" : @"iPhone" localized]] delegate:nil cancelButtonTitle:nil otherButtonTitles:[@"Ok" localized], nil] show];
        }
    }
}];