在 iOS 7 问题中检测静音开关

Posted

技术标签:

【中文标题】在 iOS 7 问题中检测静音开关【英文标题】:Detecting Silent Switch in iOS 7 issue 【发布时间】:2013-09-23 04:42:33 【问题描述】:

我正在使用以下代码来检查 iPhone 静音开关是打开还是关闭:-

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

它在 ios 6 及更低版本中运行良好,但在 iOS 7 中它总是给出 TRUE 值。所以,请任何人告诉,如何解决这个问题。

提前致谢。

【问题讨论】:

你是通过xib或storyboard中的IBAction连接这段代码吗? @karthika:- 不,上面的代码已经写在 viewDidLoad 中,然后在按钮操作中检查silentSwitch 是打开还是关闭。 检查按钮操作是否通过 TouchUpInside 或 ValueChanged 连接?我在 IOS7 中也遇到了这个问题。 【参考方案1】:

它在 iOS 7 中不起作用,如果您查看它在 iOS 7 中不起作用的原因,它在 iOS 6 中从未真正起作用。此解决方案基于相同的代码,因此所有归功于原作者不过。

    mute.caf 保留在 SharkfoodMuteSwitchDetector 中。 创建一个名为 HASilentSwitchDetector(或其他)的新类,或替换 SharkfoodMuteSwitchDetector 中的代码。

在头文件中:

#import <AudioToolbox/AudioToolbox.h>

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

@interface HASilentSwitchDetector : NSObject

+ (void)ifMute:(HASilentSwitchDetectorBlock)then;

@end

在实现文件中:

#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

这样使用:

[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];
        
    
];

【讨论】:

当然,在您的情况下,您似乎依赖于重复的回调,因此您必须重新实现该功能(我发现这是一种浪费)。一个简单的计时器调用 ifMute: 每秒就足够了,并且不会比之前模式中使用的原始无限播放循环更浪费。 这对我很有用。非常感谢 :) 奖励:当手机没有静音时(至少在 iPhone 5s 上),这似乎也大大减少了安静的 嘶嘶声

以上是关于在 iOS 7 问题中检测静音开关的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中检测铃声开关状态?

iOS响铃/静音开关设置为静音模式时没有声音

在 iOS 7 中检测静音模式

AVAudioSessionCategoryPlayAndRecord 未检测到静音开关

如何强制 WKWebView 忽略 iOS 上的硬件静音开关?

iOS 铃声开关使网络音频静音