【问题标题】:Detect the state of silent mode in iOS检测iOS中静音模式的状态
【发布时间】:2016-01-09 21:28:26
【问题描述】:

我有一个应用程序使用 AudioServicesPlaySystemSound(1104) 方法在某些点击事件上播放声音。它响应静音模式和非静音模式的状态,并相应地静音。

但是,无论振动开关处于什么状态,AudioServicesPlaySystemSound(1150) 都会播放。

如何检查振动模式的状态,以便在用户期望的时候静音?

谢谢

【问题讨论】:

    标签: ios


    【解决方案1】:

    似乎有一个开源项目可以做到这一点。见here for the code and a sample projectRBDMuteSwitch 是这里的关键类。您使用它(作为单例),并将您的班级设置为RDBMuteSwitch 的代表,以获取有关开关状态的通知。您会在切换更改或第一次致电[[RBDMuteSwitch sharedInstance] detectMuteSwitch] 时收到通知。在 iOS 9 上测试。

    这是 RBDMuteSwitch.m 的重要内容,以防 github 链接失效:

    - (void)playbackComplete {
        if ([(id)self.delegate respondsToSelector:@selector(isMuted:)]) {
            // If playback is far less than 100ms then we know the device is muted
            if (soundDuration < 0.010) {
                [delegate isMuted:YES];
            }
            else {
                [delegate isMuted:NO];
            }
        }
        [playbackTimer invalidate];
    }
    
    static void soundCompletionCallback (SystemSoundID mySSID, void* myself) {
        AudioServicesRemoveSystemSoundCompletion (mySSID);
        [[RBDMuteSwitch sharedInstance] playbackComplete];
    }
    
    - (void)incrementTimer {
        soundDuration = soundDuration + 0.001;
    }
    
    - (void)detectMuteSwitch {
    #if TARGET_IPHONE_SIMULATOR
        // The simulator doesn't support detection and can cause a crash so always return muted
        if ([(id)self.delegate respondsToSelector:@selector(isMuted:)]) {
            [self.delegate isMuted:YES];
        }
        return;
    #endif
    
    #if __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
        // iOS 5+ doesn't allow mute switch detection using state length detection
        // So we need to play a blank 100ms file and detect the playback length
        soundDuration = 0.0;
        CFURLRef        soundFileURLRef;
        SystemSoundID   soundFileObject;
    
        // Get the main bundle for the app
        CFBundleRef mainBundle = CFBundleGetMainBundle();
    
        // Get the URL to the sound file to play
        soundFileURLRef  =  CFBundleCopyResourceURL(mainBundle,
                                                    CFSTR ("detection"),
                                                    CFSTR ("aiff"),
                                                    NULL);
    
        // Create a system sound object representing the sound file
        AudioServicesCreateSystemSoundID (soundFileURLRef,
                                          &soundFileObject);
    
        AudioServicesAddSystemSoundCompletion (soundFileObject,NULL,NULL,
                                               soundCompletionCallback,
                                               (void*) self);
    
        // Start the playback timer
        playbackTimer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(incrementTimer) userInfo:nil repeats:YES];
        // Play the sound
        AudioServicesPlaySystemSound(soundFileObject);
        return;
    #else
        // This method doesn't work under iOS 5+
        CFStringRef state;
        UInt32 propertySize = sizeof(CFStringRef);
        AudioSessionInitialize(NULL, NULL, NULL, NULL);
        AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
        if(CFStringGetLength(state) > 0) {
            if ([(id)self.delegate respondsToSelector:@selector(isMuted:)]) {
                [self.delegate isMuted:NO];
            }
        }
        if ([(id)self.delegate respondsToSelector:@selector(isMuted:)]) {
            [self.delegate isMuted:YES];
        }
        return;
    #endif
    }
    

    本质上,代码所做的是调用AudioServicesPlaySystemSound() 获取已知持续时间的无声声音片段,并测试播放需要多长时间。如果播放持续时间小于预期时间,则表示静音开关已打开。

    【讨论】:

    • 这不适用于最新的 iOS 版本,如 iOS 8、9。
    • @AnilkumariOSdeveloper,我在 iOS 9(.0) 上对其进行了测试。您的项目中可能还有其他问题。无法仅用“这不起作用”来判断。
    猜你喜欢
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 2014-04-27
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    相关资源
    最近更新 更多